packages/ssoinabox-webui/root/usr/local/share/ssoinabox/htdocs/includes/smarty/sysplugins/smarty_internal_compilebase.php
author Dan Fuhry <dan@enanocms.org>
Sat, 23 Feb 2013 14:26:38 -0500
changeset 9 f4bf6556fb9f
parent 0 3906ca745819
permissions -rw-r--r--
Merged
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     1
<?php
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     2
/**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     3
 * Smarty Internal Plugin CompileBase
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     4
 *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     5
 * @package Smarty
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     6
 * @subpackage Compiler
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     7
 * @author Uwe Tews
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     8
 */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
     9
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    10
/**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    11
 * This class does extend all internal compile plugins
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    12
 *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    13
 * @package Smarty
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    14
 * @subpackage Compiler
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    15
 */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    16
abstract class Smarty_Internal_CompileBase {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    17
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    18
    /**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    19
     * Array of names of required attribute required by tag
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    20
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    21
     * @var array
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    22
     */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    23
    public $required_attributes = array();
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    24
    /**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    25
     * Array of names of optional attribute required by tag
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    26
     * use array('_any') if there is no restriction of attributes names
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    27
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    28
     * @var array
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    29
     */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    30
    public $optional_attributes = array();
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    31
    /**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    32
     * Shorttag attribute order defined by its names
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    33
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    34
     * @var array
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    35
     */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    36
    public $shorttag_order = array();
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    37
    /**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    38
     * Array of names of valid option flags
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    39
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    40
     * @var array
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    41
     */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    42
    public $option_flags = array('nocache');
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    43
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    44
    /**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    45
     * This function checks if the attributes passed are valid
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    46
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    47
     * The attributes passed for the tag to compile are checked against the list of required and
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    48
     * optional attributes. Required attributes must be present. Optional attributes are check against
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    49
     * the corresponding list. The keyword '_any' specifies that any attribute will be accepted
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    50
     * as valid
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    51
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    52
     * @param object $compiler   compiler object
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    53
     * @param array  $attributes attributes applied to the tag
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    54
     * @return array of mapped attributes for further processing
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    55
     */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    56
    public function getAttributes($compiler, $attributes)
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    57
    {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    58
        $_indexed_attr = array();
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    59
        // loop over attributes
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    60
        foreach ($attributes as $key => $mixed) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    61
            // shorthand ?
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    62
            if (!is_array($mixed)) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    63
                // option flag ?
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    64
                if (in_array(trim($mixed, '\'"'), $this->option_flags)) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    65
                    $_indexed_attr[trim($mixed, '\'"')] = true;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    66
                    // shorthand attribute ?
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    67
                } else if (isset($this->shorttag_order[$key])) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    68
                    $_indexed_attr[$this->shorttag_order[$key]] = $mixed;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    69
                } else {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    70
                    // too many shorthands
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    71
                    $compiler->trigger_template_error('too many shorthand attributes', $compiler->lex->taglineno);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    72
                }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    73
                // named attribute
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    74
            } else {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    75
                $kv = each($mixed);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    76
                // option flag?
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    77
                if (in_array($kv['key'], $this->option_flags)) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    78
                    if (is_bool($kv['value'])) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    79
                        $_indexed_attr[$kv['key']] = $kv['value'];
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    80
                    } else if (is_string($kv['value']) && in_array(trim($kv['value'], '\'"'), array('true', 'false'))) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    81
                        if (trim($kv['value']) == 'true') {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    82
                            $_indexed_attr[$kv['key']] = true;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    83
                        } else {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    84
                            $_indexed_attr[$kv['key']] = false;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    85
                        }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    86
                    } else if (is_numeric($kv['value']) && in_array($kv['value'], array(0, 1))) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    87
                        if ($kv['value'] == 1) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    88
                            $_indexed_attr[$kv['key']] = true;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    89
                        } else {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    90
                            $_indexed_attr[$kv['key']] = false;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    91
                        }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    92
                    } else {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    93
                        $compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", $compiler->lex->taglineno);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    94
                    }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    95
                    // must be named attribute
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    96
                } else {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    97
                    reset($mixed);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    98
                    $_indexed_attr[key($mixed)] = $mixed[key($mixed)];
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
    99
                }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   100
            }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   101
        }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   102
        // check if all required attributes present
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   103
        foreach ($this->required_attributes as $attr) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   104
            if (!array_key_exists($attr, $_indexed_attr)) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   105
                $compiler->trigger_template_error("missing \"" . $attr . "\" attribute", $compiler->lex->taglineno);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   106
            }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   107
        }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   108
        // check for unallowed attributes
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   109
        if ($this->optional_attributes != array('_any')) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   110
            $tmp_array = array_merge($this->required_attributes, $this->optional_attributes, $this->option_flags);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   111
            foreach ($_indexed_attr as $key => $dummy) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   112
                if (!in_array($key, $tmp_array) && $key !== 0) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   113
                    $compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", $compiler->lex->taglineno);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   114
                }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   115
            }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   116
        }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   117
        // default 'false' for all option flags not set
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   118
        foreach ($this->option_flags as $flag) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   119
            if (!isset($_indexed_attr[$flag])) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   120
                $_indexed_attr[$flag] = false;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   121
            }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   122
        }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   123
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   124
        return $_indexed_attr;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   125
    }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   126
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   127
    /**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   128
     * Push opening tag name on stack
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   129
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   130
     * Optionally additional data can be saved on stack
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   131
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   132
     * @param object    $compiler   compiler object
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   133
     * @param string    $openTag    the opening tag's name
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   134
     * @param mixed     $data       optional data saved
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   135
     */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   136
    public function openTag($compiler, $openTag, $data = null)
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   137
    {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   138
        array_push($compiler->_tag_stack, array($openTag, $data));
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   139
    }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   140
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   141
    /**
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   142
     * Pop closing tag
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   143
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   144
     * Raise an error if this stack-top doesn't match with expected opening tags
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   145
     *
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   146
     * @param object       $compiler    compiler object
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   147
     * @param array|string $expectedTag the expected opening tag names
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   148
     * @return mixed any type the opening tag's name or saved data
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   149
     */
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   150
    public function closeTag($compiler, $expectedTag)
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   151
    {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   152
        if (count($compiler->_tag_stack) > 0) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   153
            // get stacked info
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   154
            list($_openTag, $_data) = array_pop($compiler->_tag_stack);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   155
            // open tag must match with the expected ones
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   156
            if (in_array($_openTag, (array) $expectedTag)) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   157
                if (is_null($_data)) {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   158
                    // return opening tag
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   159
                    return $_openTag;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   160
                } else {
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   161
                    // return restored data
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   162
                    return $_data;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   163
                }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   164
            }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   165
            // wrong nesting of tags
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   166
            $compiler->trigger_template_error("unclosed {" . $_openTag . "} tag");
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   167
            return;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   168
        }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   169
        // wrong nesting of tags
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   170
        $compiler->trigger_template_error("unexpected closing tag", $compiler->lex->taglineno);
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   171
        return;
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   172
    }
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   173
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   174
}
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   175
3906ca745819 First commit!
Dan Fuhry <dan@fuhry.us>
parents:
diff changeset
   176
?>