[Checkins] SVN: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/ Configuration was drastically changed. Many conveniences were taken

Martijn Faassen faassen at startifact.com
Tue Nov 23 12:04:42 EST 2010


Log message for revision 118540:
  Configuration was drastically changed. Many conveniences were taken 
  away in favor of just passing the information to NeededInclusions.
  

Changed:
  U   hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt
  U   hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py
  U   hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py

-=-
Modified: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt
===================================================================
--- hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt	2010-11-23 16:58:57 UTC (rev 118539)
+++ hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt	2010-11-23 17:04:41 UTC (rev 118540)
@@ -231,23 +231,23 @@
 enable them. Later sections below go into more details.
 
 * minified resources. Resources can specify minified versions using
-  the mode system. You can use ``hurry.resource.mode('minified')``
-  somewhere in the request handling of your application. This will
-  make sure that resources included on your page are supplied as
-  minified versions, if these are available.
+  the mode system. You can pass the ``mode`` argument 'minified' to
+  CurrentlyNeededInclusions. This will make sure that resources
+  included on your page are supplied as minified versions, if these
+  are available. XXX
 
 * rolling up of resources.  Resource libraries can specify rollup
   resources that combine multiple resources into one. This reduces the
   amount of server requests to be made by the web browser, and can
-  help with caching. To enable rolling up, call
-  ``hurry.resource.rollup`` somewhere in your request handling.
+  help with caching. To enable rolling up, you can set the ``rollup``
+  argument to CurrentlyNeededInclusions. XXX
 
 * javascript inclusions at the bottom of the web page. If your
   framework integration uses the special ``render_topbottom`` method,
   you can enable the inclusion of javascript files at the bottom by
   calling ``hurry.resource.bottom()``. This will only include
   resources at the bottom that have explicitly declared themselves to
-  be *bottom-safe*. You can declare a resource bottom safe by passing
+  be *bottom-safe*. XXX You can declare a resource bottom safe by passing
   ``bottom=True`` when constructing a ``ResourceInclusion``. If you
   want to force all javascript to be including at the bottom of the
   page by default, you can call ``hurry.resource.bottom(force=True)``.
@@ -394,7 +394,8 @@
 We can however also get the resource for mode ``debug`` and get
 ``k-debug.js``::
 
-  >>> needed.mode('debug')
+  >>> needed = NeededInclusions(mode='debug')
+  >>> needed.need(k1)
   >>> needed.inclusions()
   [<ResourceInclusion 'k-debug.js' in library 'foo'>]
 
@@ -403,18 +404,19 @@
 
   >>> k2 = ResourceInclusion(foo, 'k2.js',
   ...                        debug=ResourceInclusion(foo, 'k2-debug.js'))
-  >>> needed = NeededInclusions()
-  >>> needed.need(k2)
 
 By default we get ``k2.js``::
 
+  >>> needed = NeededInclusions()
+  >>> needed.need(k2)
   >>> needed.inclusions()
   [<ResourceInclusion 'k2.js' in library 'foo'>]
 
 We can however also get the resource for mode ``debug`` and get
 ``k2-debug.js``::
 
-  >>> needed.mode('debug')
+  >>> needed = NeededInclusions(mode='debug')
+  >>> needed.need(k2)
   >>> needed.inclusions()
   [<ResourceInclusion 'k2-debug.js' in library 'foo'>]
 
@@ -424,8 +426,7 @@
 If you request a mode and a resource doesn't support it, it will
 return its default resource instead::
 
-  >>> needed = NeededInclusions()
-  >>> needed.mode('minified')
+  >>> needed = NeededInclusions(mode='minified')
   >>> needed.need(k1)
   >>> needed.inclusions()
   [<ResourceInclusion 'k.js' in library 'foo'>]
@@ -452,40 +453,8 @@
 
 If the developer wants to debug, he will need to disable rolling up
 (by calling ``hurry.resource.rollup(disable=True)``, or by simply
-never calling ``hurry.resource.rollup()`` in the request cycle).
+never calling ``hurry.resource.rollup()`` in the request cycle). XXX
 
-Mode convenience
-================
-
-Like for ``need``, there is also a convenience spelling for
-``mode``. It uses ``ICurrentNeededInclusions``, which we've already
-set up to look at the ``request.needed`` variable. Let's set up
-a new request::
-
-  >>> request = Request()
-
-Let's set up a resource and need it::
-
-  >>> l1 = ResourceInclusion(foo, 'l1.js', debug='l1-debug.js')
-  >>> l1.need()
-
-Let's look at the resources needed by default::
-
-  >>> c = get_current_needed_inclusions()
-  >>> c.inclusions()
-  [<ResourceInclusion 'l1.js' in library 'foo'>]
-
-Let's now change the mode using the convenience
-``hurry.resource.mode`` spelling::
-
-  >>> from hurry.resource import mode
-  >>> mode('debug')
-
-When we request the resources now, we get them in the ``debug`` mode::
-
-  >>> c.inclusions()
-  [<ResourceInclusion 'l1-debug.js' in library 'foo'>]
-
 "Rollups"
 =========
 
@@ -514,14 +483,8 @@
 
 Let's enable rollups::
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
 
-The convenience spelling to enable rollups during request handling
-looks like this::
-
-  hurry.resource.rollup()
-
 If we now find multiple resources that are also part of a
 consolidation, the system automatically collapses them::
 
@@ -533,8 +496,7 @@
 The system will by default only consolidate exactly. That is, if only a single
 resource out of two is present, the consolidation will not be triggered::
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(b1)
   >>> needed.inclusions()
   [<ResourceInclusion 'b1.js' in library 'foo'>]
@@ -548,16 +510,14 @@
 
 It will not roll up one resource::
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(c1)
   >>> needed.inclusions()
   [<ResourceInclusion 'c1.css' in library 'foo'>]
 
 Neither will it roll up two resources::
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(c1)
   >>> needed.need(c2)
   >>> needed.inclusions()
@@ -566,8 +526,7 @@
 
 It will however roll up three resources::
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(c1)
   >>> needed.need(c2)
   >>> needed.need(c3)
@@ -597,8 +556,7 @@
 We will see ``giantd.js`` kick in even if we only require ``d1`` and
 ``d2``::
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(d1)
   >>> needed.need(d2)
   >>> needed.inclusions()
@@ -607,8 +565,7 @@
 In fact even if we only need a single resource the eager superseder will
 show up instead::
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(d1)
   >>> needed.inclusions()
   [<ResourceInclusion 'giantd.js' in library 'foo'>]
@@ -619,8 +576,7 @@
   >>> d4 = ResourceInclusion(foo, 'd4.js')
   >>> giantd_bigger = ResourceInclusion(foo, 'giantd-bigger.js',
   ...   supersedes=[d1, d2, d3, d4], eager_superseder=True)
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(d1)
   >>> needed.need(d2)
   >>> needed.inclusions()
@@ -631,8 +587,7 @@
 
   >>> giantd_noneager = ResourceInclusion(foo, 'giantd-noneager.js',
   ...   supersedes=[d1, d2, d3, d4])
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(d1)
   >>> needed.need(d2)
   >>> needed.need(d3)
@@ -652,8 +607,7 @@
   ...   supersedes=[e1, e2])
   >>> giante_three = ResourceInclusion(foo, 'giante-three.js',
   ...   supersedes=[e1, e2, e3])
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(e1)
   >>> needed.need(e2)
   >>> needed.need(e3)
@@ -667,13 +621,14 @@
   >>> giantf = ResourceInclusion(foo, 'giantf.js', supersedes=[f1, f2],
   ...                            debug='giantf-debug.js')
 
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(f1)
   >>> needed.need(f2)
   >>> needed.inclusions()
   [<ResourceInclusion 'giantf.js' in library 'foo'>]
-  >>> needed.mode('debug')
+  >>> needed = NeededInclusions(rollup=True, mode='debug')
+  >>> needed.need(f1)
+  >>> needed.need(f2)
   >>> needed.inclusions()
   [<ResourceInclusion 'giantf-debug.js' in library 'foo'>]
 
@@ -685,13 +640,14 @@
   >>> g2 = ResourceInclusion(foo, 'g2.js')
   >>> giantg = ResourceInclusion(foo, 'giantg.js', supersedes=[g1, g2],
   ...                            debug='giantg-debug.js')
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(g1)
   >>> needed.need(g2)
   >>> needed.inclusions()
   [<ResourceInclusion 'giantg.js' in library 'foo'>]
-  >>> needed.mode('debug')
+  >>> needed = NeededInclusions(rollup=True, mode='debug')
+  >>> needed.need(g1)
+  >>> needed.need(g2)
   >>> needed.inclusions()
   [<ResourceInclusion 'giantg.js' in library 'foo'>]
 
@@ -701,8 +657,7 @@
   >>> h1 = ResourceInclusion(foo, 'h1.js', debug='h1-debug.js')
   >>> h2 = ResourceInclusion(foo, 'h2.js', debug='h2-debug.js')
   >>> gianth = ResourceInclusion(foo, 'gianth.js', supersedes=[h1, h2])
-  >>> needed = NeededInclusions()
-  >>> needed.rollup()
+  >>> needed = NeededInclusions(rollup=True)
   >>> needed.need(h1)
   >>> needed.need(h2)
   >>> needed.inclusions()
@@ -711,7 +666,9 @@
 Since there is no superseder for the debug mode, we will get the two
 resources, not rolled up::
 
-  >>> needed.mode('debug')
+  >>> needed = NeededInclusions(rollup=True, mode='debug')
+  >>> needed.need(h1)
+  >>> needed.need(h2)
   >>> needed.inclusions()
   [<ResourceInclusion 'h1-debug.js' in library 'foo'>,
    <ResourceInclusion 'h2-debug.js' in library 'foo'>]
@@ -731,18 +688,16 @@
 Now let's try to render these inclusions::
 
   >>> print needed.render()
-  Traceback (most recent call last):
-    ...
-  AttributeError: 'NoneType' object has no attribute 'endswith'
+  <link rel="stylesheet" type="text/css" href="/fanstatic/:hash:.../foo/b.css" />
+  <script type="text/javascript" src="/fanstatic/:hash:.../foo/a.js"></script>
+  <script type="text/javascript" src="/fanstatic/:hash:.../foo/c.js"></script>
 
-That didn't work. In order to render an inclusion, we need to tell
-``hurry.resource`` the base URL for a resource inclusion. We
-already know the relative URL, so we need to specify how to get a URL
-to the library itself that the relative URL can be added to.
+In some cases it is useful for the application to control where the
+resources should be published. This can be controlled by setting the
+``base_url`` attribute of the currently needed inclusions. We already
+know the relative URL, so we need to specify how to get a URL to the
+library itself that the relative URL can be added to.
 
-Before rendering the resources, the base_url attribute has to be set
-on the needed inclusions.
-
 For the purposes of this document, we define a function that renders
 resources as some static URL on localhost::
 
@@ -757,19 +712,6 @@
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/a.js"></script>
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
 
-Let's set this a currently needed inclusions::
-
-  >>> request.needed = needed
-
-There is a function available as well for rendering the resources for
-the currently needed inclusion::
-
-  >>> from hurry import resource
-  >>> print resource.render()
-  <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/a.js"></script>
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
-
 Hashing resources
 =================
 
@@ -788,7 +730,7 @@
 hash of the resource's contents, so it will look like
 /foo/fanstatic/:hash:12345/myresource instead of /foo/myresource.
 
-  >>> print resource.render()
+  >>> print needed.render()
   <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/a.js"></script>
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
@@ -869,6 +811,8 @@
 To insert the resources directly in HTML we can use ``render_into_html``
 on ``needed``::
 
+  >>> needed = NeededInclusions(base_url='http://localhost/static/')
+  >>> needed.need(y1)
   >>> print needed.render_into_html(html)
   <html><head>
       <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
@@ -876,16 +820,6 @@
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
   something more</head></html>
 
-The top-level convenience function does this for the currently needed
-resources::
-
-  >>> print resource.render_into_html(html)
-  <html><head>
-      <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/a.js"></script>
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
-  something more</head></html>
-
 See below for a way to insert into HTML when bottom fragments are
 involved.
 
@@ -911,10 +845,11 @@
   <BLANKLINE>
 
 There is effectively no change; all the resources are still on the
-top. We can enable bottom rendering by calling the ``bottom`` method before
-we render::
+top. We now try with enabling bottom::
 
-  >>> needed.bottom()
+  >>> needed = NeededInclusions(base_url='http://localhost/static/', 
+  ...   bottom=True)
+  >>> needed.need(y1)
 
 Since none of the resources indicated it was safe to render them at
 the bottom, even this explicit call will not result in any changes::
@@ -927,10 +862,12 @@
   >>> print bottom
   <BLANKLINE>
 
-``bottom(force=True)`` will however force all javascript inclusions to be
-rendered in the bottom fragment::
+We can however force all javascript inclusions to be rendered in the
+bottom fragment using ``force_bottom``::
 
-  >>> needed.bottom(force=True)
+  >>> needed = NeededInclusions(base_url='http://localhost/static/', 
+  ...   bottom=True, force_bottom=True)
+  >>> needed.need(y1)
   >>> top, bottom = needed.render_topbottom()
   >>> print top
   <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
@@ -946,8 +883,7 @@
 When we start over without ``bottom`` enabled, we get this resource
 show up in the top fragment after all::
 
-  >>> needed = NeededInclusions()
-  >>> needed.base_url = 'http://localhost/static/'
+  >>> needed = NeededInclusions(base_url='http://localhost/static/')
   >>> needed.need(y1)
   >>> needed.need(y2)
 
@@ -962,7 +898,10 @@
 
 We now tell the system that it's safe to render inclusions at the bottom::
 
-  >>> needed.bottom()
+  >>> needed = NeededInclusions(base_url='http://localhost/static', 
+  ...   bottom=True)
+  >>> needed.need(y1)
+  >>> needed.need(y2)
 
 We now see the resource ``y2`` show up in the bottom fragment::
 
@@ -974,22 +913,14 @@
   >>> print bottom
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/y2.js"></script>
 
-There's also a convenience function for the currently needed inclusion::
-
-  >>> request.needed = needed
-  >>> top, bottom = resource.render_topbottom()
-  >>> print top
-  <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/a.js"></script>
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
-  >>> print bottom
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/y2.js"></script>
-
 When we force bottom rendering of Javascript, there is no effect of
 making a resource bottom-safe: all ``.js`` resources will be rendered
 at the bottom anyway::
 
-  >>> needed.bottom(force=True)
+  >>> needed = NeededInclusions(base_url='http://localhost/static/', 
+  ...   bottom=True, force_bottom=True)
+  >>> needed.need(y1)
+  >>> needed.need(y2)
   >>> top, bottom = needed.render_topbottom()
   >>> print top
   <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
@@ -1032,16 +963,6 @@
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
   <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/y2.js"></script></body></html>
 
-There's also a function available to do this for the currently needed
-resources::
-
-  >>> print resource.render_topbottom_into_html(html)
-  <html><head>
-      <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/:hash:.../foo/b.css" />
-  rest of head</head><body>rest of body<script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/a.js"></script>
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/c.js"></script>
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/y2.js"></script></body></html>
-
 Using WSGI middleware to insert into HTML
 =========================================
 
@@ -1096,40 +1017,6 @@
   >>> res.body
   '<html><head></head><body</body></html>'
 
-bottom convenience
-==================
-
-Like for ``need`` and ``mode``, there is also a convenience spelling for
-``bottom``::
-
-  >>> request = Request()
-  >>> l1 = ResourceInclusion(foo, 'l1.js', bottom=True)
-  >>> l1.need()
-
-Let's look at the resources needed by default::
-
-  >>> c = get_current_needed_inclusions()
-  >>> c.base_url = 'http://localhost/static'
-  >>> top, bottom = c.render_topbottom()
-  >>> print top
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/l1.js"></script>
-  >>> print bottom
-  <BLANKLINE>
-
-Let's now change the bottom mode using the convenience
-``hurry.resource.bottom`` spelling::
-
-  >>> from hurry.resource import bottom
-  >>> bottom()
-
-Re-rendering will show it's honoring the bottom setting::
-
-  >>> top, bottom = c.render_topbottom()
-  >>> print top
-  <BLANKLINE>
-  >>> print bottom
-  <script type="text/javascript" src="http://localhost/static/fanstatic/:hash:.../foo/l1.js"></script>
-
 Generating resource code
 ========================
 

Modified: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py
===================================================================
--- hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py	2010-11-23 16:58:57 UTC (rev 118539)
+++ hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py	2010-11-23 17:04:41 UTC (rev 118540)
@@ -4,10 +4,6 @@
                                  GroupInclusion,
                                  NeededInclusions)
 
-from hurry.resource.core import (mode, bottom, rollup,
-                                 render, render_topbottom, render_into_html,
-                                 render_topbottom_into_html)
-
 from hurry.resource.core import (sort_inclusions_topological,
                                  sort_inclusions_by_extension,
                                  generate_code)

Modified: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py
===================================================================
--- hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py	2010-11-23 16:58:57 UTC (rev 118539)
+++ hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py	2010-11-23 17:04:41 UTC (rev 118540)
@@ -176,34 +176,24 @@
     return ResourceInclusion(library, inclusion)
 
 class NeededInclusions(object):
-    def __init__(self):
-        self.base_url = None
-        self._inclusions = []
-        self._mode = None
-        self._rollup = False
-        self._bottom = False
-        self._force_bottom = False
+    def __init__(self,
+                 base_url='/',
+                 inclusions=None,
+                 mode=None,
+                 rollup=False,
+                 bottom=False,
+                 force_bottom=False,
+                 ):
+        self.base_url = base_url
+        self._inclusions = inclusions or []
+        self._mode = mode
+        self._rollup = rollup
+        self._bottom = bottom
+        self._force_bottom = force_bottom
 
     def need(self, inclusion):
         self._inclusions.append(inclusion)
 
-    def mode(self, mode):
-        self._mode = mode
-
-    def bottom(self, force=False, disable=False):
-        if disable:
-            self._bottom = False
-            self._force_bottom = False
-            return
-        self._bottom = True
-        if force:
-            self._force_bottom = True
-
-    def rollup(self, disable=False):
-        if disable:
-            self._rollup = False
-        self._rollup = True
-
     def _sorted_inclusions(self):
         return reversed(sorted(self._inclusions, key=lambda i: i.depth()))
 
@@ -306,38 +296,6 @@
 def get_current_needed_inclusions():
     return _plugin.get_current_needed_inclusions()
 
-def mode(mode):
-    """Set the mode for the currently needed resources.
-    """
-    needed = _plugin.get_current_needed_inclusions()
-    needed.mode(mode)
-
-def bottom(force=False, disable=False):
-    """Try to include resources at the bottom of the page, not just on top.
-    """
-    needed = _plugin.get_current_needed_inclusions()
-    needed.bottom(force, disable)
-
-def rollup(disable=False):
-    needed = _plugin.get_current_needed_inclusions()
-    needed.rollup(disable)
-
-def render():
-    needed = _plugin.get_current_needed_inclusions()
-    return needed.render()
-
-def render_into_html(html):
-    needed = _plugin.get_current_needed_inclusions()
-    return needed.render_into_html(html)
-
-def render_topbottom():
-    needed = _plugin.get_current_needed_inclusions()
-    return needed.render_topbottom()
-
-def render_topbottom_into_html(html):
-    needed = _plugin.get_current_needed_inclusions()
-    return needed.render_topbottom_into_html(html)
-
 def apply_mode(inclusions, mode):
     return [inclusion.mode(mode) for inclusion in inclusions]
 



More information about the checkins mailing list