[gjs: 14/43] CI: Add eqeqeq to eslint rules



commit adf9a22adcda7e00ecb30f30d24d7318c72e841d
Author: Philip Chimento <philip chimento gmail com>
Date:   Sat Aug 3 20:37:01 2019 -0700

    CI: Add eqeqeq to eslint rules
    
    Using == for comparisons is a well-known gotcha that we should avoid.
    
    However, we ignore the rule in tweener.js to reduce the risk of
    regressions in the unmaintained code.

 .eslintrc.yml                           |  1 +
 examples/calc.js                        |  4 ++--
 examples/gio-cat.js                     |  2 +-
 installed-tests/js/testGDBus.js         |  4 ++--
 installed-tests/js/testGObjectClass.js  |  2 +-
 installed-tests/js/testLegacyClass.js   |  2 +-
 installed-tests/js/testLegacyGObject.js |  2 +-
 installed-tests/js/testTweener.js       |  4 ++--
 modules/_bootstrap/debugger.js          | 20 +++++++++----------
 modules/_legacy.js                      | 18 ++++++++---------
 modules/format.js                       | 12 ++++++------
 modules/lang.js                         |  9 ++++-----
 modules/overrides/GLib.js               | 34 ++++++++++++++++-----------------
 modules/overrides/GObject.js            |  2 +-
 modules/overrides/Gio.js                | 14 +++++++-------
 modules/signals.js                      |  8 ++++----
 modules/tweener/tweener.js              |  2 +-
 17 files changed, 70 insertions(+), 70 deletions(-)
---
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 99c4628b..c03a2f09 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -35,6 +35,7 @@ rules:
     - error
     - property
   eol-last: error
+  eqeqeq: error
   indent:
     - error
     - 4
diff --git a/examples/calc.js b/examples/calc.js
index 0b45732e..860c17ff 100644
--- a/examples/calc.js
+++ b/examples/calc.js
@@ -30,7 +30,7 @@ function pressedEquals() {
     calcVal = calcVal.replace('tan', 'Math.tan');
     calcVal = eval(calcVal);
     // Avoid ridiculous amounts of precision from toString.
-    if (calcVal == Math.floor(calcVal))
+    if (calcVal === Math.floor(calcVal))
         calcVal = Math.floor(calcVal);
     else // bizarrely gjs loses str.toFixed() somehow?!
         calcVal = Math.floor(calcVal * 10000) / 10000;
@@ -48,7 +48,7 @@ function pressedNumber(button) {
 }
 
 function swapSign() {
-    calcVal = ((calcVal[0] == '-') ?
+    calcVal = ((calcVal[0] === '-') ?
         calcVal.substring(1) : `-${calcVal}`);
     updateDisplay();
 }
diff --git a/examples/gio-cat.js b/examples/gio-cat.js
index 92d05347..640df637 100644
--- a/examples/gio-cat.js
+++ b/examples/gio-cat.js
@@ -23,7 +23,7 @@ function cat(filename) {
     loop.run();
 }
 
-if (ARGV.length != 1)
+if (ARGV.length !== 1)
     printerr('Usage: gio-cat.js filename');
 else
     cat(ARGV[0]);
diff --git a/installed-tests/js/testGDBus.js b/installed-tests/js/testGDBus.js
index 50af1b01..85c21634 100644
--- a/installed-tests/js/testGDBus.js
+++ b/installed-tests/js/testGDBus.js
@@ -117,7 +117,7 @@ class Test {
     }
 
     nonJsonFrobateStuff(i) {
-        if (i == 42)
+        if (i === 42)
             return '42 it is!';
         else
             return 'Oops';
@@ -268,7 +268,7 @@ describe('Exported DBus object', function () {
         });
 
         while (waitId && (!test[property] ||
-                          (value !== undefined && test[property] != value)))
+                          (value !== undefined && test[property] !== value)))
             loop.get_context().iteration(true);
 
         if (waitId)
diff --git a/installed-tests/js/testGObjectClass.js b/installed-tests/js/testGObjectClass.js
index 4b4087f9..5aa522a9 100644
--- a/installed-tests/js/testGObjectClass.js
+++ b/installed-tests/js/testGObjectClass.js
@@ -39,7 +39,7 @@ const MyObject = GObject.registerClass({
     }
 
     set readwrite(val) {
-        if (val == 'ignore')
+        if (val === 'ignore')
             return;
 
         this._readwrite = val;
diff --git a/installed-tests/js/testLegacyClass.js b/installed-tests/js/testLegacyClass.js
index 89a86f3b..afd8a7c6 100644
--- a/installed-tests/js/testLegacyClass.js
+++ b/installed-tests/js/testLegacyClass.js
@@ -178,7 +178,7 @@ const Accessor = new Lang.Class({
     },
 
     set value(val) {
-        if (val != 42)
+        if (val !== 42)
             throw TypeError('Value is not a magic number');
         this._val = val;
     },
diff --git a/installed-tests/js/testLegacyGObject.js b/installed-tests/js/testLegacyGObject.js
index b2a360bc..a4c515b2 100644
--- a/installed-tests/js/testLegacyGObject.js
+++ b/installed-tests/js/testLegacyGObject.js
@@ -54,7 +54,7 @@ const MyObject = new GObject.Class({
     },
 
     set readwrite(val) {
-        if (val == 'ignore')
+        if (val === 'ignore')
             return;
 
         this._readwrite = val;
diff --git a/installed-tests/js/testTweener.js b/installed-tests/js/testTweener.js
index afbb06e4..e5b596b9 100644
--- a/installed-tests/js/testTweener.js
+++ b/installed-tests/js/testTweener.js
@@ -322,9 +322,9 @@ describe('Tweener', function () {
             discrete: ['x'],
             transition: 'linear',
             onUpdate: function() {
-                if (objectA.x != Math.floor(objectA.x))
+                if (objectA.x !== Math.floor(objectA.x))
                     objectA.xFraction = true;
-                if (objectA.y != Math.floor(objectA.y))
+                if (objectA.y !== Math.floor(objectA.y))
                     objectA.yFraction = true;
             },
         });
diff --git a/modules/_bootstrap/debugger.js b/modules/_bootstrap/debugger.js
index aafe6372..758df59e 100644
--- a/modules/_bootstrap/debugger.js
+++ b/modules/_bootstrap/debugger.js
@@ -99,10 +99,10 @@ Object.defineProperty(Debugger.Frame.prototype, 'num', {
 });
 
 Debugger.Frame.prototype.describeFrame = function() {
-    if (this.type == 'call') {
+    if (this.type === 'call') {
         return `${this.callee.name || '<anonymous>'}(${
             this.arguments.map(dvToString).join(', ')})`;
-    } else if (this.type == 'global') {
+    } else if (this.type === 'global') {
         return 'toplevel';
     } else {
         return `${this.type} code`;
@@ -199,7 +199,7 @@ backtraceCommand.helpText = `USAGE
 
 function setCommand(rest) {
     var space = rest.indexOf(' ');
-    if (space == -1) {
+    if (space === -1) {
         print('Invalid set <option> <value> command');
     } else {
         var name = rest.substr(0, space);
@@ -229,9 +229,9 @@ function splitPrintOptions(s, style) {
     const m = /^\/(\w+)/.exec(s);
     if (!m)
         return [s, style];
-    if (m[1].indexOf('p') != -1)
+    if (m[1].startsWith('p'))
         style.pretty = true;
-    if (m[1].indexOf('b') != -1)
+    if (m[1].startsWith('b'))
         style.brief = true;
     return [s.substr(m[0].length).trimLeft(), style];
 }
@@ -471,7 +471,7 @@ function doStepOrNext(kind) {
 
     function stepEntered(newFrame) {
         print(`entered frame: ${newFrame.describeFull()}`);
-        if (!kind.until || newFrame.line == kind.stopLine) {
+        if (!kind.until || newFrame.line === kind.stopLine) {
             topFrame = focusedFrame = newFrame;
             return repl();
         }
@@ -489,17 +489,17 @@ function doStepOrNext(kind) {
             stop = true;
         } else if (kind.until) {
             // running until a given line is reached
-            if (this.line == kind.stopLine)
+            if (this.line === kind.stopLine)
                 stop = true;
         } else {
             // regular step; stop whenever the line number changes
-            if ((this.line != startLine) || (this != startFrame))
+            if ((this.line !== startLine) || (this !== startFrame))
                 stop = true;
         }
 
         if (stop) {
             topFrame = focusedFrame = this;
-            if (focusedFrame != startFrame)
+            if (focusedFrame !== startFrame)
                 print(focusedFrame.describeFull());
             return repl();
         }
@@ -751,7 +751,7 @@ PARAMETERS
 //
 function breakcmd(cmd) {
     cmd = cmd.trimLeft();
-    if ("!@#$%^&*_+=/?.,<>:;'\"".indexOf(cmd.substr(0, 1)) != -1)
+    if ("!@#$%^&*_+=/?.,<>:;'\"".includes(cmd.substr(0, 1)))
         return [cmd.substr(0, 1), cmd.substr(1).trimLeft()];
     var m = /\s+|(?=\/)/.exec(cmd);
     if (m === null)
diff --git a/modules/_legacy.js b/modules/_legacy.js
index 263aa1e5..43416b73 100644
--- a/modules/_legacy.js
+++ b/modules/_legacy.js
@@ -61,7 +61,7 @@ function getMetaClass(params) {
 function Class(params) {
     let metaClass = getMetaClass(params);
 
-    if (metaClass && metaClass != this.constructor)
+    if (metaClass && metaClass !== this.constructor)
         return new metaClass(...arguments);
     else
         return this._construct.apply(this, arguments);
@@ -467,7 +467,7 @@ function defineGObjectLegacyObjects(GObject) {
                 _createSignals(this.$gtype, signals);
 
             Object.getOwnPropertyNames(params).forEach(function(name) {
-                if (name == 'Name' || name == 'Extends' || name == 'Abstract')
+                if (['Name', 'Extends', 'Abstract'].includes(name))
                     return;
 
                 let descriptor = Object.getOwnPropertyDescriptor(params, name);
@@ -475,10 +475,10 @@ function defineGObjectLegacyObjects(GObject) {
                 if (typeof descriptor.value === 'function') {
                     let wrapped = this.prototype[name];
 
-                    if (name.slice(0, 6) == 'vfunc_') {
+                    if (name.startsWith('vfunc_')) {
                         this.prototype[Gi.hook_up_vfunc_symbol](name.slice(6),
                             wrapped);
-                    } else if (name.slice(0, 3) == 'on_') {
+                    } else if (name.startsWith('on_')) {
                         let id = GObject.signal_lookup(name.slice(3).replace('_', '-'), this.$gtype);
                         if (id !== 0) {
                             GObject.signal_override_class_closure(id, this.$gtype, function() {
@@ -499,10 +499,10 @@ function defineGObjectLegacyObjects(GObject) {
             if (!proto)
                 return false;
 
-            // If proto == GObject.Object.prototype, then
+            // If proto === GObject.Object.prototype, then
             // proto.__proto__ is Object, so "proto instanceof GObject.Object"
             // will return false.
-            return proto == GObject.Object.prototype ||
+            return proto === GObject.Object.prototype ||
                 proto instanceof GObject.Object;
         },
 
@@ -674,7 +674,7 @@ function defineGtkLegacyObjects(GObject, Gtk) {
                 Gtk.Widget.set_css_name.call(this, cssName);
 
             if (template) {
-                if (typeof template == 'string' &&
+                if (typeof template === 'string' &&
                     template.startsWith('resource:///'))
                     Gtk.Widget.set_template_from_resource.call(this, template.slice(11));
                 else
@@ -702,11 +702,11 @@ function defineGtkLegacyObjects(GObject, Gtk) {
             if (!proto)
                 return false;
 
-            // If proto == Gtk.Widget.prototype, then
+            // If proto === Gtk.Widget.prototype, then
             // proto.__proto__ is GObject.InitiallyUnowned, so
             // "proto instanceof Gtk.Widget"
             // will return false.
-            return proto == Gtk.Widget.prototype ||
+            return proto === Gtk.Widget.prototype ||
                 proto instanceof Gtk.Widget;
         },
     });
diff --git a/modules/format.js b/modules/format.js
index 5e841c27..7208a19b 100644
--- a/modules/format.js
+++ b/modules/format.js
@@ -9,21 +9,21 @@ function vprintf(str, args) {
     let usePos = false;
     return str.replace(/%(?:([1-9][0-9]*)\$)?(I+)?([0-9]+)?(?:\.([0-9]+))?(.)/g, function (str, posGroup, 
flagsGroup, widthGroup, precisionGroup, genericGroup) {
         if (precisionGroup !== '' && precisionGroup !== undefined &&
-            genericGroup != 'f')
+            genericGroup !== 'f')
             throw new Error("Precision can only be specified for 'f'");
 
         let hasAlternativeIntFlag = (flagsGroup &&
-            flagsGroup.indexOf('I') != -1);
-        if (hasAlternativeIntFlag && genericGroup != 'd')
+            flagsGroup.indexOf('I') !== -1);
+        if (hasAlternativeIntFlag && genericGroup !== 'd')
             throw new Error("Alternative output digits can only be specfied for 'd'");
 
         let pos = parseInt(posGroup, 10) || 0;
-        if (usePos == false && i == 0)
+        if (!usePos && i === 0)
             usePos = pos > 0;
-        if (usePos && pos == 0 || !usePos && pos > 0)
+        if (usePos && pos === 0 || !usePos && pos > 0)
             throw new Error('Numbered and unnumbered conversion specifications cannot be mixed');
 
-        let fillChar = (widthGroup && widthGroup[0] == '0') ? '0' : ' ';
+        let fillChar = (widthGroup && widthGroup[0] === '0') ? '0' : ' ';
         let width = parseInt(widthGroup, 10) || 0;
 
         function fillWidth(s, c, w) {
diff --git a/modules/lang.js b/modules/lang.js
index ce256830..d58ae4ea 100644
--- a/modules/lang.js
+++ b/modules/lang.js
@@ -50,8 +50,7 @@ function copyProperties(source, dest) {
 
 function copyPublicProperties(source, dest) {
     for (let property in source) {
-        if (typeof(property) == 'string' &&
-            property.substring(0, 1) == '_')
+        if (typeof(property) === 'string' && property.startsWith('_'))
             continue;
         else
             _copyProperty(source, dest, property);
@@ -68,19 +67,19 @@ function copyPublicProperties(source, dest) {
  * @type: function
  */
 function bind(obj, callback) {
-    if (typeof(obj) != 'object') {
+    if (typeof(obj) !== 'object') {
         throw new Error(`first argument to Lang.bind() must be an object, not ${
             typeof(obj)}`);
     }
 
-    if (typeof(callback) != 'function') {
+    if (typeof(callback) !== 'function') {
         throw new Error(`second argument to Lang.bind() must be a function, not ${
             typeof(callback)}`);
     }
 
     // Use ES5 Function.prototype.bind, but only if not passing any bindArguments,
     // because ES5 has them at the beginning, not at the end
-    if (arguments.length == 2)
+    if (arguments.length === 2)
         return callback.bind(obj);
 
     let me = obj;
diff --git a/modules/overrides/GLib.js b/modules/overrides/GLib.js
index 14fbf47b..41d8f81c 100644
--- a/modules/overrides/GLib.js
+++ b/modules/overrides/GLib.js
@@ -28,30 +28,30 @@ function _readSingleType(signature, forceSimple) {
     let char = signature.shift();
     let isSimple = false;
 
-    if (SIMPLE_TYPES.indexOf(char) == -1) {
+    if (!SIMPLE_TYPES.includes(char)) {
         if (forceSimple)
             throw new TypeError('Invalid GVariant signature (a simple type was expected)');
     } else {
         isSimple = true;
     }
 
-    if (char == 'm' || char == 'a')
+    if (char === 'm' || char === 'a')
         return [char].concat(_readSingleType(signature, false));
-    if (char == '{') {
+    if (char === '{') {
         let key = _readSingleType(signature, true);
         let val = _readSingleType(signature, false);
         let close = signature.shift();
-        if (close != '}')
+        if (close !== '}')
             throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}"');
         return [char].concat(key, val, close);
     }
-    if (char == '(') {
+    if (char === '(') {
         let res = [char];
         while (true) {
-            if (signature.length == 0)
+            if (signature.length === 0)
                 throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
             let next = signature[0];
-            if (next == ')') {
+            if (next === ')') {
                 signature.shift();
                 return res.concat(next);
             }
@@ -61,7 +61,7 @@ function _readSingleType(signature, forceSimple) {
     }
 
     // Valid types are simple types, arrays, maybes, tuples, dictionary entries and variants
-    if (!isSimple && char != 'v')
+    if (!isSimple && char !== 'v')
         throw new TypeError(`Invalid GVariant signature (${char} is not a valid type)`);
 
     return [char];
@@ -75,7 +75,7 @@ function _makeBytes(byteArray) {
 }
 
 function _packVariant(signature, value) {
-    if (signature.length == 0)
+    if (signature.length === 0)
         throw new TypeError('GVariant signature cannot be empty');
 
     let char = signature.shift();
@@ -109,7 +109,7 @@ function _packVariant(signature, value) {
     case 'v':
         return GLib.Variant.new_variant(value);
     case 'm':
-        if (value != null) {
+        if (value !== null) {
             return GLib.Variant.new_maybe(null, _packVariant(signature, value));
         } else {
             return GLib.Variant.new_maybe(new GLib.VariantType(
@@ -117,11 +117,11 @@ function _packVariant(signature, value) {
         }
     case 'a': {
         let arrayType = _readSingleType(signature, false);
-        if (arrayType[0] == 's') {
+        if (arrayType[0] === 's') {
             // special case for array of strings
             return GLib.Variant.new_strv(value);
         }
-        if (arrayType[0] == 'y') {
+        if (arrayType[0] === 'y') {
             // special case for array of bytes
             let bytes;
             if (typeof value === 'string') {
@@ -137,7 +137,7 @@ function _packVariant(signature, value) {
         }
 
         let arrayValue = [];
-        if (arrayType[0] == '{') {
+        if (arrayType[0] === '{') {
             // special case for dictionaries
             for (let key in value) {
                 let copy = [].concat(arrayType);
@@ -158,12 +158,12 @@ function _packVariant(signature, value) {
         let children = [];
         for (let i = 0; i < value.length; i++) {
             let next = signature[0];
-            if (next == ')')
+            if (next === ')')
                 break;
             children.push(_packVariant(signature, value[i]));
         }
 
-        if (signature[0] != ')')
+        if (signature[0] !== ')')
             throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
         signature.shift();
         return GLib.Variant.new_tuple(children);
@@ -172,7 +172,7 @@ function _packVariant(signature, value) {
         let key = _packVariant(signature, value[0]);
         let child = _packVariant(signature, value[1]);
 
-        if (signature[0] != '}')
+        if (signature[0] !== '}')
             throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}")');
         signature.shift();
 
@@ -282,7 +282,7 @@ function _init() {
         let signature = Array.prototype.slice.call(sig);
 
         let variant = _packVariant(signature, value);
-        if (signature.length != 0)
+        if (signature.length !== 0)
             throw new TypeError('Invalid GVariant signature (more than one single complete type)');
 
         return variant;
diff --git a/modules/overrides/GObject.js b/modules/overrides/GObject.js
index 9a8f6658..bc0c7ebe 100644
--- a/modules/overrides/GObject.js
+++ b/modules/overrides/GObject.js
@@ -40,7 +40,7 @@ var _gtkInternalChildren = Symbol('GTK widget template internal children');
 var _gtkTemplate = Symbol('GTK widget template');
 
 function registerClass(klass) {
-    if (arguments.length == 2) {
+    if (arguments.length === 2) {
         // The two-argument form is the convenient syntax without ESnext
         // decorators and class data properties. The first argument is an
         // object with meta info such as properties and signals. The second
diff --git a/modules/overrides/Gio.js b/modules/overrides/Gio.js
index 91ea7eed..a08b4861 100644
--- a/modules/overrides/Gio.js
+++ b/modules/overrides/Gio.js
@@ -100,9 +100,9 @@ function _proxyInvoker(methodName, sync, inSignature, argArray) {
     while (argArray.length > signatureLength) {
         var argNum = argArray.length - 1;
         var arg = argArray.pop();
-        if (typeof(arg) == 'function' && !sync) {
+        if (typeof(arg) === 'function' && !sync) {
             replyFunc = arg;
-        } else if (typeof(arg) == 'number') {
+        } else if (typeof(arg) === 'number') {
             flags = arg;
         } else if (arg instanceof Gio.Cancellable) {
             cancellable = arg;
@@ -148,7 +148,7 @@ function _proxyInvoker(methodName, sync, inSignature, argArray) {
 }
 
 function _logReply(result, exc) {
-    if (exc != null)
+    if (exc !== null)
         log(`Ignored exception from dbus method: ${exc}`);
 }
 
@@ -272,7 +272,7 @@ function _makeProxyWrapper(interfaceXml) {
 
 
 function _newNodeInfo(constructor, value) {
-    if (typeof value == 'string')
+    if (typeof value === 'string')
         return constructor(value);
     throw TypeError(`Invalid type ${Object.prototype.toString.call(value)}`);
 }
@@ -331,7 +331,7 @@ function _handleMethodCall(info, impl, methodName, parameters, invocation) {
                 invocation.return_gerror(e);
             } else {
                 let name = e.name;
-                if (name.indexOf('.') == -1) {
+                if (!name.includes('.')) {
                     // likely to be a normal JS error
                     name = `org.gnome.gjs.JSError.${name}`;
                 }
@@ -354,7 +354,7 @@ function _handleMethodCall(info, impl, methodName, parameters, invocation) {
                 if (outSignature.includes('h') &&
                     retval[retval.length - 1] instanceof Gio.UnixFDList) {
                     outFdList = retval.pop();
-                } else if (outArgs.length == 1) {
+                } else if (outArgs.length === 1) {
                     // if one arg, we don't require the handler wrapping it
                     // into an Array
                     retval = [retval];
@@ -382,7 +382,7 @@ function _handleMethodCall(info, impl, methodName, parameters, invocation) {
 function _handlePropertyGet(info, impl, propertyName) {
     let propInfo = info.lookup_property(propertyName);
     let jsval = this[propertyName];
-    if (jsval != undefined)
+    if (jsval !== undefined)
         return new GLib.Variant(propInfo.signature, jsval);
     else
         return null;
diff --git a/modules/signals.js b/modules/signals.js
index 229f014f..e4ef9f80 100644
--- a/modules/signals.js
+++ b/modules/signals.js
@@ -33,7 +33,7 @@ const Lang = imports.lang;
 function _connect(name, callback) {
     // be paranoid about callback arg since we'd start to throw from emit()
     // if it was messed up
-    if (typeof(callback) != 'function')
+    if (typeof(callback) !== 'function')
         throw new Error('When connecting signal must give a callback that is a function');
 
     // we instantiate the "signal machinery" only on-demand if anything
@@ -64,7 +64,7 @@ function _disconnect(id) {
         let length = this._signalConnections.length;
         for (i = 0; i < length; ++i) {
             let connection = this._signalConnections[i];
-            if (connection.id == id) {
+            if (connection.id === id) {
                 if (connection.disconnected)
                     throw new Error(`Signal handler id ${id} already disconnected`);
 
@@ -114,7 +114,7 @@ function _emit(name, ...args) {
     let length = this._signalConnections.length;
     for (i = 0; i < length; ++i) {
         let connection = this._signalConnections[i];
-        if (connection.name == name)
+        if (connection.name === name)
             handlers.push(connection);
     }
 
@@ -148,7 +148,7 @@ function _emit(name, ...args) {
 }
 
 function _addSignalMethod(proto, functionName, func) {
-    if (proto[functionName] && proto[functionName] != func)
+    if (proto[functionName] && proto[functionName] !== func)
         log(`WARNING: addSignalMethods is replacing existing ${proto} ${functionName} method`);
 
     proto[functionName] = func;
diff --git a/modules/tweener/tweener.js b/modules/tweener/tweener.js
index ce6afeb3..66f637e2 100644
--- a/modules/tweener/tweener.js
+++ b/modules/tweener/tweener.js
@@ -1,5 +1,5 @@
 /* -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil; -*- */
-/* eslint-disable block-scoped-var */
+/* eslint-disable block-scoped-var, eqeqeq */
 
 /* Copyright 2008  litl, LLC. */
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]