'require' search path

I wish ‘require’ would count the current directory as the directory the file
is in, rather than the directory the script is being run from. My test
scripts do

require ‘test/tc_default’

This works fine if you’re running the test script which runs all the tests, as
it resides in the parent directory. However, if you cd into the test
directory and run a test case directly, it can’t find it, since it’s looking
for ‘test/test/tc_default’ instead, which of course doesn’t exist.

The same goes for my executable file, sitting in the bin directory. I’ve had
to add a line

$: << FILE.sub(/\w*$/, ‘’) + ‘…/lib’

in order to get it to run out of the tarball (I don’t want to have to install
it while testing…) Then I added a pre-setup.rb (hook for install.rb) which
removes this line when the file is installed. This works, but it is very
kludgy to me - surely there’s a better way? (Oh, and it means once you run
install.rb, the file is no longer the same one you downloaded… this in
itself is bad, I think.)

Tim Bates

···


tim@bates.id.au

Hi Tim,

Maybe you can add to $: with ruby -I for those situations when you need to go
into a directory to run a specific test as outlined above.


Signed,
Holden Glova

···

On Sun, 12 Jan 2003 00:23, Tim Bates wrote:

I wish ‘require’ would count the current directory as the directory the
file is in, rather than the directory the script is being run from. My test
scripts do

require ‘test/tc_default’

This works fine if you’re running the test script which runs all the tests,
as it resides in the parent directory. However, if you cd into the test
directory and run a test case directly, it can’t find it, since it’s
looking for ‘test/test/tc_default’ instead, which of course doesn’t exist.

The same goes for my executable file, sitting in the bin directory. I’ve
had to add a line

$: << FILE.sub(/\w*$/, ‘’) + ‘…/lib’

in order to get it to run out of the tarball (I don’t want to have to
install it while testing…) Then I added a pre-setup.rb (hook for
install.rb) which removes this line when the file is installed. This works,
but it is very kludgy to me - surely there’s a better way? (Oh, and it
means once you run install.rb, the file is no longer the same one you
downloaded… this in itself is bad, I think.)

Tim Bates

Hi Tim,

Good points. Check out ProjectDirectoryStructure on the wiki for some
tips I gathered when I asked a similar-ish question. Please suggest
anything I can add to the page.

Briefly, though, I found no killer way to do what you’re after with
running test cases, so I set my own standard procedure for running
tests and stuck to it. I can’t retrieve the code now, but basically I
had a “test/master.rb” that ran every test. If you gave it CL
arguments, it ran only these files. That was good enough for me.
Restriction: my test directory was flat.

Cheers,
Gavin

···

On Saturday, January 11, 2003, 10:23:51 PM, Tim wrote:

I wish ‘require’ would count the current directory as the directory the file
is in, rather than the directory the script is being run from. My test
scripts do

require ‘test/tc_default’

This works fine if you’re running the test script which runs all the tests, as
it resides in the parent directory. However, if you cd into the test
directory and run a test case directly, it can’t find it, since it’s looking
for ‘test/test/tc_default’ instead, which of course doesn’t exist.
[…]

wish granted:

module Kernel
alias :require_basic :require
def require(file_or_directory)
if FileTest.directory?(file_or_directory)
require “#{file_or_directory}/#{file_or_directory}”
else
fp = File.dirname(File.expand_path(file_or_directory))
$: << fp
r = require_basic file_or_directory
i = $LOAD_PATH.index(fp)
$LOAD_PATH.delete_at(i) if i
return r
end
end
end

please test and improve upon. i have only done so minorly. notice also that it
adds my much wished for ability to auto-require things like ‘dbi/dbi’ just by
using ‘dbi’.

this has been added to tomslib/rubylib (new release still pending)

···

On Saturday 11 January 2003 04:23 am, Tim Bates wrote:

I wish ‘require’ would count the current directory as the directory the
file is in, rather than the directory the script is being run from.


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

I have my make file that runs my tests create a directory
with a parallel structure that parallels the installed
directory tree. In this directory I put soft links to the
local files. This way I can test the new code in any directory,
even while old code is installed. Using this method I don’t have
to have special require code nor do I have to modify the source.

EG.
make test

will create

mylib
±myclass1.rb->/path/to/myclass1.rb # soft link
±myclass2.rb->/path/to/myclass2.rb # soft link

and will run

ruby -I mylib ts_mycode.rb

To run code that is installed, just run without the -I.

···

On Saturday, 11 January 2003 at 20:23:51 +0900, Tim Bates wrote:

I wish ‘require’ would count the current directory as the directory the file
is in, rather than the directory the script is being run from. My test
scripts do


Jim Freeze

Furious activity is no substitute for understanding.
– H. H. Williams

Hi –

I wish ‘require’ would count the current directory as the directory the
file is in, rather than the directory the script is being run from.

wish granted:

module Kernel
alias :require_basic :require
def require(file_or_directory)
if FileTest.directory?(file_or_directory)
require “#{file_or_directory}/#{file_or_directory}”
else
fp = File.dirname(File.expand_path(file_or_directory))
$: << fp
r = require_basic file_or_directory
i = $LOAD_PATH.index(fp)
$LOAD_PATH.delete_at(i) if i
return r
end
end
end

please test and improve upon. i have only done so minorly. notice also that it
adds my much wished for ability to auto-require things like ‘dbi/dbi’ just by
using ‘dbi’.

And seems to do away with the ability to require things like ‘scanf’
just by using ‘scanf’…

candle:~/hacking/ruby$ ruby req.rb
req.rb:10:in require': No such file to load -- scanf/scanf (LoadError) from req.rb:10:in require’
from req.rb:6:in `require’
from req.rb:18

In any event, I think it might be best to consider writing a new
method, rather than overriding require, if you want to create a new
package-loading functionality. ‘require’ and ‘load’ are spoken for,
and you’re going to end up quarantining your code from the rest of
Ruby if you redefine them.

David

···

On Sun, 12 Jan 2003, Tom Sawyer wrote:

On Saturday 11 January 2003 04:23 am, Tim Bates wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

This does not solve Tim’s problem, as I understand it.

“I wish ‘require’ would count the current directory as the directory the
file is in, rather than the directory the script is being run from.”
sounds like he wants “require” to behave like C’s “#include” and html’s
“href”: relative paths should be relative to the directory of the
file that contains the “require” statement / “#include” directive / “href”
attribute. Your solution would treat the path as relative to the current
directory of the ruby process which is what he does explicitly not want
(Tim calls this “the directory the script is being run from”).

How about this:

def import(what)
require File.join(File.dirname(caller[0]), what)
end

and use “import” instead of “require”.

T

···

On Sun, 12 Jan 2003, Tom Sawyer wrote:

On Saturday 11 January 2003 04:23 am, Tim Bates wrote:

I wish ‘require’ would count the current directory as the directory the
file is in, rather than the directory the script is being run from.

wish granted:
[…]

David,

well, hopefully it just needs a fix. i don’t seem to have scanf. so i can’t
test this. i take it though that the problem is that there is a scanf
directory and a scanf include file. the require is finding the directory
first and thus failing. hmm…just need to make sure it looks for the file
first, prior to trying it as a “directory-require”. how to do?..

yes, there may be some unexpected “successful” requires due to this code that
normally would fail, but (once fixed) i see no reason that it should cause
previous code to break. so there should be no issue of quarantining.

also, that was an aside adjustment. the second part is the more intersesting
of the two alterations. see any problems with that? i esspecially like this.
i find it awfully painful to have to go through my files and change requires
simple b/c i’ve decided to put them in a different directory.

···

On Saturday 11 January 2003 06:38 pm, dblack@candle.superlink.net wrote:

please test and improve upon. i have only done so minorly. notice also
that it adds my much wished for ability to auto-require things like
‘dbi/dbi’ just by using ‘dbi’.

And seems to do away with the ability to require things like ‘scanf’
just by using ‘scanf’…

candle:~/hacking/ruby$ ruby req.rb
req.rb:10:in require': No such file to load -- scanf/scanf (LoadError) from req.rb:10:in require’
from req.rb:6:in `require’
from req.rb:18

In any event, I think it might be best to consider writing a new
method, rather than overriding require, if you want to create a new
package-loading functionality. ‘require’ and ‘load’ are spoken for,
and you’re going to end up quarantining your code from the rest of
Ruby if you redefine them.


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

I wish ‘require’ would count the current directory as the directory the
file is in, rather than the directory the script is being run from.

wish granted:
[…]

This does not solve Tim’s problem, as I understand it.

“I wish ‘require’ would count the current directory as the directory the
file is in, rather than the directory the script is being run from.”
sounds like he wants “require” to behave like C’s “#include” and html’s
“href”: relative paths should be relative to the directory of the
file that contains the “require” statement / “#include” directive / “href”
attribute. Your solution would treat the path as relative to the current
directory of the ruby process which is what he does explicitly not want
(Tim calls this “the directory the script is being run from”).

umm…unless i’m missing something, and the test i ran somehow worked for
unbeknown reasons, i would have to say this exactly what i have done. there
may be some flaw in the design that i have overlooked, but this is the simple
contruct: when a file is required, the location of that file being required
is added to the load path. thus any subsequent requires from within that
require and (requires within those requires) will be findable without
specifiying the path relative to the running process.

How about this:

def import(what)
require File.join(File.dirname(caller[0]), what)
end

and use “import” instead of “require”.

ah, the use of caller is nice! i’ll have to think about its use in my
solution. very nice solution. short and sweet. the only problem i see with it
is that it can’t be used inplace of require, which for me defeats part of the
purpose.

···

On Monday 13 January 2003 05:30 am, Tobias Peters wrote:

On Sun, 12 Jan 2003, Tom Sawyer wrote:

On Saturday 11 January 2003 04:23 am, Tim Bates wrote:


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

Hi –

please test and improve upon. i have only done so minorly. notice also
that it adds my much wished for ability to auto-require things like
‘dbi/dbi’ just by using ‘dbi’.

And seems to do away with the ability to require things like ‘scanf’
just by using ‘scanf’…

candle:~/hacking/ruby$ ruby req.rb
req.rb:10:in require': No such file to load -- scanf/scanf (LoadError) from req.rb:10:in require’
from req.rb:6:in `require’
from req.rb:18

In any event, I think it might be best to consider writing a new
method, rather than overriding require, if you want to create a new
package-loading functionality. ‘require’ and ‘load’ are spoken for,
and you’re going to end up quarantining your code from the rest of
Ruby if you redefine them.

David,

well, hopefully it just needs a fix. i don’t seem to have scanf. so i can’t
test this. i take it though that the problem is that there is a scanf
directory and a scanf include file. the require is finding the directory
first and thus failing. hmm…just need to make sure it looks for the file
first, prior to trying it as a “directory-require”. how to do?..

There’s a file called ‘scanf.rb’ in site-ruby/1.6/, no scanf
directory.

yes, there may be some unexpected “successful” requires due to this code that
normally would fail, but (once fixed) i see no reason that it should cause
previous code to break. so there should be no issue of quarantining.

Well, if your first point is true, then I don’t think you can be sure
the second point is true :slight_smile:

Why not just rename the method? There’s no need to compete with Ruby
for this namespace.

also, that was an aside adjustment. the second part is the more intersesting
of the two alterations. see any problems with that? i esspecially like this.
i find it awfully painful to have to go through my files and change requires
simple b/c i’ve decided to put them in a different directory.

That means that you want to be able to have two file placements which
are evaluated identically by ‘require’. You want “require ‘xxx’” to
be able to mean either of two different things.

However, problems arise when both of those things exist. Let’s say
you start with:

…/site-ruby/1.6/my_lib/
…/site-ruby/1.6/my_lib/my_lib.rb

and you rewrite require so you can do:

require ‘my_lib’

and it loads my_lib/my_lib.rb. What happens now if you add a new file:

…/site-ruby/1.6/my_lib.rb

This isn’t a very likely scenario, but my point is that if you use one
expression to represent two things, then you cannot later fully
recover the difference between those things.

‘require’ actually deals with things like this already, in some
situations (like file.rb and file.so both existing). But by changing
it, you risk introducing incompatible solutions to new problems.

At the very least (or the very most), you’d probably want to write
a superset of ‘require’. If ‘require’ succeeds, stop. If it fails,
apply your new set of extra rules.

David

···

On Sun, 12 Jan 2003, Tom Sawyer wrote:

On Saturday 11 January 2003 06:38 pm, dblack@candle.superlink.net wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Here’s a test that fails:
$ mkdir testrequire

$ echo ’
module Kernel
alias :require_basic :require
def require(file_or_directory)
if FileTest.directory?(file_or_directory)
require “#{file_or_directory}/#{file_or_directory}”
else
fp = File.dirname(File.expand_path(file_or_directory))
$: << fp
r = require_basic file_or_directory
i = $LOAD_PATH.index(fp)
$LOAD_PATH.delete_at(i) if i
return r
end
end
end

require “file2.rb”
’ >testrequire/file1.rb

$ echo “puts ‘in file2.rb’” >testrequire/file2.rb

$ ruby testrequire/file1.rb
testrequire/file1.rb:10:in require': No such file to load -- file2.rb (LoadError) from testrequire/file1.rb:10:in require’
from testrequire/file1.rb:18

$ (cd testrequire && ruby file1.rb)
in file2.rb

T

···

On Tue, 14 Jan 2003, Tom Sawyer wrote:

wish granted:

This does not solve Tim’s problem, as I understand it.

umm…unless i’m missing something, and the test i ran somehow worked for
unbeknown reasons, i would have to say this exactly what i have done. there

how does that fail? i don’t see why it should. like i said i don’t have scanf
so i can’t test this specific case (should i have it? if so, i wonder why i
do not.) but if there is no directory scanf then what is causing it to run
that section of code? hmmm… well, i look at it some more in awhile.

and i’ll respond to the rest in a bit…

BTW thanks for looking at this

···

On Saturday 11 January 2003 07:33 pm, dblack@candle.superlink.net wrote:

There’s a file called ‘scanf.rb’ in site-ruby/1.6/, no scanf
directory.


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

Well, if your first point is true, then I don’t think you can be sure
the second point is true :slight_smile:

true in the sense that the only difference should be that in the very rare
case there may be a require that succeeds where before it would have thrown
an error --and a very very rare exception indeed. i don’t think that this is
significant enough to warrant it an unacceptable consequence.

Why not just rename the method? There’s no need to compete with Ruby
for this namespace.

well, for me that would defeat the purpose. the whole point is to make my life
easier. i.e. use less brain power to get more done. but that is the
alternative if this proves to have unacceptable back-compatability
consequences.

That means that you want to be able to have two file placements which
are evaluated identically by ‘require’. You want “require ‘xxx’” to
be able to mean either of two different things.

However, problems arise when both of those things exist. Let’s say
you start with:

…/site-ruby/1.6/my_lib/
…/site-ruby/1.6/my_lib/my_lib.rb

and you rewrite require so you can do:

require ‘my_lib’

and it loads my_lib/my_lib.rb. What happens now if you add a new file:

…/site-ruby/1.6/my_lib.rb

This isn’t a very likely scenario, but my point is that if you use one
expression to represent two things, then you cannot later fully
recover the difference between those things.

yes there is this consideration, but i would want it to behave with
precedence, is all. that is to say the file should get required, not the dir,
in such a case, as it would currently.

‘require’ actually deals with things like this already, in some
situations (like file.rb and file.so both existing). But by changing
it, you risk introducing incompatible solutions to new problems.

i think, as stated above and before in not-so-many-words, is that the risk can
be exactly determined. i believe, from what i can thus phathom, is that the
singular case as given above (i.e. the very rare exception) is the only
possible incompatability and as such is almost mute since an error would be
thrown anyway.

At the very least (or the very most), you’d probably want to write
a superset of ‘require’. If ‘require’ succeeds, stop. If it fails,
apply your new set of extra rules.

i agree and threw this together. note i did this in two seconds, it hasn’t
been fully tested. do you see any problem with this approach?

alias :require_basic :require
def require(file_or_directory)
begin
fp = File.dirname(File.expand_path(file_or_directory))
$: << fp
r = require_basic file_or_directory
i = $LOAD_PATH.index(fp)
$LOAD_PATH.delete_at(i) if i
return r
rescue
if FileTest.directory?(file_or_directory)
require “#{file_or_directory}/#{file_or_directory}”
else
raise
end
end
end

···

On Saturday 11 January 2003 07:33 pm, dblack@candle.superlink.net wrote:


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

quite right! thanks Tobias!

my solution failed to take into consideration the initial directory offset of
the running process, thus running: “ruby testerequire/file1.rb” would not
catch the testrequire directory on the first call to require and fail
subsequently.

so, i have taken your #import solution, using caller[0], and mixed it with
mine, plus a touch of clean up. let’s see if this does the trick:

alias :require_basic :require
def require(file_or_directory)
begin
fp = File.expand_path(File.dirname(caller[0]))
$: << fp
r = require_basic file_or_directory
i = $:.index(fp)
$:.delete_at(i) if i
return r
rescue
if FileTest.directory?(file_or_directory)
require “#{file_or_directory}/#{file_or_directory}”
else
raise
end
end
end

notice that, on the recommendation of David, i made the “directory require”
portion only happen if all else fails. so hopefully this covers all
contingencies now while being backward compatable (on the whole). even so, i
bet it can still be cleaned up a bit more. what’s your take?

···

On Tuesday 14 January 2003 02:34 am, Tobias Peters wrote:

Here’s a test that fails: …


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

note that this is in reference to the “directory require” change. as to the
“current directory” change, there is the potential of conflicting file names,
but as Ruby searches the $LOAD_PATH in sequence and the current directory is
added to the end, this should cause no problems.

···

On Sunday 12 January 2003 12:10 am, Tom Sawyer wrote:

On Saturday 11 January 2003 07:33 pm, dblack@candle.superlink.net wrote:

Well, if your first point is true, then I don’t think you can be sure
the second point is true :slight_smile:

true in the sense that the only difference should be that in the very rare
case there may be a require that succeeds where before it would have thrown
an error --and a very very rare exception indeed. i don’t think that this
is significant enough to warrant it an unacceptable consequence.


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

i have just run into a potential conflict. i named a file to require ‘DBI.rb’.
of course the problem with this is that it could require the typical DBI
library rather than my file. (actually not in this case but it becomes
conceivable in other cases) of course i could rename my file to avoid such a
conflict, but that means being very aware of the fact that DBI (or other lib)
exists. so i have taken up the alternate suggestion:

def import(file_name)
require File.join(File.dirname(caller[0]), file_name)
end

alias :require_basic :require
def require(file_or_directory)
begin
require_basic file_or_directory
rescue
if FileTest.directory?(file_or_directory)
require “#{file_or_directory}/#{file_or_directory}”
else
raise
end
end
end

···

On Tuesday 14 January 2003 05:59 am, Tom Sawyer wrote:

alias :require_basic :require
def require(file_or_directory)
begin
fp = File.expand_path(File.dirname(caller[0]))
$: << fp
r = require_basic file_or_directory
i = $:.index(fp)
$:.delete_at(i) if i
return r
rescue
if FileTest.directory?(file_or_directory)
require “#{file_or_directory}/#{file_or_directory}”
else
raise
end
end
end


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:-:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= * =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.