Login Register

The Package System and Custom Builds

A Dojo custom build speeds performance by doing the following:

  1. First, it groups together modules into layers. A layer, which is one big .js file, loads faster than the individual .js modules that comprise it
  2. Second, it interns external non-JavaScript files. This is most important for Dijit templates, which are kept in a separate HTML file. Interning pulls the entire file in and assigns it to a string.
  3. Third, it smooshes the layer down with ShrinkSafe. ShrinkSafe removes unneeded whitepsace and comments, and compacts variable names down to smaller ones. This file downloads and parses faster than the original.
  4. Finally, it copies all non-layered scripts to the appropriate places. While this doesn't speed anything up, it ensures that all Dojo modules can be loaded, even if not present in a layer. If you use a particular module only once or twice, keeping it out of the layers makes those layers load faster.

The catch? You have to designate the modules in each layer with a profile, which is something like a Makefile or Ant script. But that's not too hard if you know your app well.

So the input of the build system is the Dojo source tree, plus any source trees for custom stuff you wish to include ... plus the profile. The output is a Dojo distribution tree which you can copy to your web server. Sweet!

Prerequisites

You need the following installed on your computer to run Dojo's build system:

Creating a Custom Profile

In the util/buildscripts/profiles directory, you will create a profile build file called foo.profile.js like this:

dependencies ={
    layers:  [
        {
        name: "mydojo.js",
        dependencies: [
            "dijit.Button",
            "dojox.wire.Wire",
            "dojox.wire.XmlWire",
            "explosive.space.Modulator"
        ]
        }
    ],
    prefixes: [
        [ "dijit", "../dijit" ],
        [ "dojox", "../dojox" ],
        [ "explosive", "../../explosive" ]
    ]
};

The dependencies section within the layer lists all the modules you call directly. Any referenced modules will also be included, so you don't have to trace back the dependency tree. Also, Dojo base modules are an implicit dependency, so you don't need to list things like "dojo.query". (Dojo core modules, however, do need to be listed.)

The modules for that layer are gathered together to make the "layer" file, in our example: "mydojo.js". Then you just load this layer file in your pages with a SCRIPT tag. Easy!

The prefixes section list any modules that need inclusion. Note our "explosive" module, which is located away from the Dojo tree. You need to list these if you use them, even if you don't want any modules from it in your layer file.

For the 1.0+: If you choose to optimize the JS files in a prefix directory (via the optimize= build parameter), you can choose to have a custom copyright text prepended to the optimized file. To do this, specify the path to a file that contains the copyright info as the third array item in the prefixes array. For instance:

prefixes: [
    [ "explosive", "../../explosive", "../../explosive/copyright.txt"]
]

If no copyright is specified in this optimize case, then by default, the dojo copyright will be used.

Running The Build

After specifying a profile file as shown above that statically specifies the resources you want to include, and saving it as /buildscripts/profiles/foo.profile.js, you run the Rhino interpreter on it and specify the profile name as a parameter. For example, from the buildscripts directory:

$ cd util/buildscripts
$ build.sh profile=foo action=release

On Windows PC's, substitute build.bat for build.sh. For both platforms, you may also specify additional build options. Run build.sh to see a list of all supported options. Here is a sample of the supported options:

profile The name of the profile to use for the build. It must be the first part of the profile file name in the profiles/ directory. For instance, to use base.profile.js, specify profile=base. Default: base
profileFile A file path to the the profile file. Use this if your profile is outside of the profiles directory. Do not specify the "profile" build option if you use "profileFile" Default: "",
action The build action(s) to run. Can be a comma-separated list, like action=clean,release. The possible build actions are: clean, release Default: "help",
version The build will be stamped with this version string Default: "0.0.0.dev",
localeList The set of locales to use when flattening i18n bundles Default: "en-gb,en-us,de-de,es-es,fr-fr,it-it,pt-br,ko-kr,zh-tw,zh-cn,ja-jp",
releaseName The name of the release. A directory inside 'releaseDir' will be created with this name Default: "dojo",
releaseDir The top level release directory where builds end up. The 'releaseName' directories will be placed inside this directory Default: "../../release/",
loader The type of dojo loader to use. "default" or "xdomain" are acceptable values." defaultValue: "default",
internStrings Turn on or off widget template/dojo.uri.cache() file interning Default: true,
optimize Specifies how to optimize module files. If "comments" is specified, then code comments are stripped. If "shrinksafe" is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If "shrinksafe.keepLines" is specified, then the Dojo compressor will be used on the files, and line returns will be preserved. If "packer" is specified, Then Dean Edwards' Packer will be used Default: "",
layerOptimize Specifies how to optimize the layer files. If "comments" is specified, then code comments are stripped. If "shrinksafe" is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If "shrinksafe.keepLines" is specified, then the Dojo compressor will be used on the layer files, and line returns will be preserved. If "packer" is specified, Then Dean Edwards' Packer will be used Default: "shrinksafe",
copyTests Turn on or off copying of test files Default: true,
log Sets the logging verbosity. See jslib/logger.js for possible integer values Default: logger.TRACE,
xdDojoPath If the loader=xdomain build option is used, then the value of this option will be used for the path to Dojo modules. The dijit and dojox paths will be assumed to be sibilings of this path. The xdDojoPath should end in '/dojo' Default: "",

Cross Domain (XDomain) Builds

Doing an xdomain build allows you to load Dojo and your custom modules from another domain.

Benefits

  • You get more connections in MSIE, since you can load from another domain. Faster loading.
  • You get increased cacheability/startup if many of your applications use the same installation.
  • Resource loading does not block the rest of the page from filling in as with Dojo's normal, synchronous loading.
  • With a local install, your ISP may charge you for all of those Dojo bits that you are serving.

Implications/Limitations

  • Not all external resources can be xdomain loaded, in particular some support files that need to be loaded from the same domain as the HTML page. See module-specifc notes below.
  • Requires a "xdomain" build of Dojo (see below for more info on how to make a xdomain build).
  • Asynchronous loading. You MUST use dojo.addOnLoad() to register a callback function to get notification of package loading. This can be used even after the initial page load. Just do the dojo.require()s that you need, and then call dojo.addOnLoad() with a callback function, and once those new packages are loaded (or if they are already loaded), then the callback will be called. This technique works even for the normal Dojo loader, so this is a good practice to use even when not using an xdomain build.
  • Avoid using document.write(): Since module can load asychnously, after the page is loaded, document.write can cause problems.

Module-specific Notes

dojo.io.iframe.create(), dijit.Editor, dijit._editor.RichText: You need to save dojo/resources/blank.html to the same domain as your HTML page and set djConfig.dojoBlankHtmlUrl to the path on that domain. Note: The dijit.Editor/dijit._editor.RichText has a bug in release 1.1.0 where it was not using this djConfig parameter. It is fixed in Dojo 1.1.1 and later.

dojo.back: You need to save dojo/resources/blank.html to the same domain as your HTML page and set djConfig.dojoIframeHistoryUrl to the path on that domain.

dojox.flash.Info() : It uses document.write() which will cause problems if dojox.flash is loaded via dojo.require().

Doing xdomain builds

$ cd util/buildscripts
$ build.sh profile=foo loader=xdomain xdDojoPath=http://my.server.com/path/to/buildoutputdir action=release

xdDojoPath is optional. It just burns in the location of dojo, dijit and dojox into the built dojo.js. If you do not specify that option, then you will need to use djConfig.modulePaths/dojo.registerModulePath() in your HTML page to set the xdomain locations for dojo, dijit and dojox. For your own custom modules, you will have to set djConfig.modulePaths/dojo.registerModulePath() even if you us the xdDojoPath build option.

For Dojo 0.9 through 1.1.x there is a bug about loading dojox.gfx with an xdomain build.. This is fixed in Dojo 1.2. If you want to use dojox.gfx with an xdomain build of Dojo 0.9-1.1.x, there are some workarounds until the bug gets fixed:

  1. Include dojox/gfx.js directly in your page with a script tag in the HTML source, after the dojo.js script tag (do not use gfx.xd.js, use gfx.js).
  2. Include dojox.gfx in a layer file that you load via a script tag in the HTML source (load the .js layer file, not the .xd.js layer file).

How to use xdomain builds in web pages

  • In djConfig, add useXDomain = true.
  • In djConfig, add a modulePaths object that maps where to find your modules.
  • Register a callback function to get notification of when the packages are loaded by using dojo.addOnLoad().
  • Optional: set a wait time in milliseconds (djConfig.xdWaitSeconds) that specifies how long the resource loader should wait for a resource to load until returning an error. Since script elements do not give information about failed or long-running requests, this timeout is used to prevent infinite waiting in the browser. An exception will be thrown to indicate a load error. The default xdWaitSeconds is 15.

XDomain Example

Here is an example showing how to load local modules along with an xdomain-loaded dojo and dijit. You can download this example.

Bugs / Pitfalls with custom builds

You really do have to do your own custom packaging of dojo in order to get the snappy performance we all want. Generally, what we have done is this:

1.) Added a dojo-build directory to our project, which holds a src version of dojo untarred.
2.) Have two header files, one for dojo-dev, and one for dojo-prod. This allows us to have the standard dojo-release for our development purposes (this file holds the link lines, djconfig, etc) and one for production, which just links to our custom dojo base file, and our custom dijit file. Our build process scrapes out the dojo.require's from our tpl templates. This way, you only have two requests for all of dojo, and your own widgetry. We also scrape out the addModule line, as that is not needed in production.
3.) The profile file as shown above lists all of the dijits , and our own widgets, that are called DIRECTLY. This is important to manage, and should be thought about whenever you add / remove a dijit or custom widget from your app. The prefixes are just dijit, and our own module. Try to embed all of your requires for each custom widget within it's Widget.js file.

For php folk, the concept of a build is pretty foreign. But eventually, as your app gets bigger, you need something like ant or phing in order to build, and deploy, your app. The dojo build process just hooks right into whatever build script you use. We fire the command line build.sh with parameters telling it where our profile file, and deployment dir (right in our js dir) should be.

Like most people, I took the tundra theme, and used it as a base for our own theme. I wanted the theme to be completely seperate from the dojo directory, in our css dir. At the top of tundra.css, you will see a relative link to the base dijit.css file. This bit us hard after our custom build. If you move your theme dir outside the dojo area, a relative link will break in a custom build (since the dojo-1.0.1 dir is not present in the production dist), but firebug cant catch that the dijit.css core file was 404. All dijits were messed up until we changed this. Our production dojo_head.tpl file links to the production custom build's dijit.css, and then our own theme css. e.g.:

@import url("js/dojo-release/dojo/dijit/themes/dijit.css");
@import url("css/themes/gq/gqdojo.css");


How to use a custom build

I've seen a lot of discussion on the boards about how one should use the custom build after you've created a layer file with additional classes compiled in. For a local Dojo build (not XDomain) as listed above, I think the correct HTML code to reference the layers is:

<script type="text/javascript" src="/js/release/dojo/dojo/dojo.js"></script>
<script type="text/javascript" src="/js/release/dojo/dojo/mydojo.js"></script>

Is this correct? The important thing to note is that you have to reference both the dojo.js and mydojo.js files, I think.

Build Profile Parameter Descriptions Table

In order to try and fully understand the dojo build profile parameters, I have attempted to describe them in the following table. If there are errors or omissions in what I have posted, please let me know and I will be happy to correct them.

For source code at version 1.0.2, this table assumes a minimal build command of the form:

./build.sh profile="yourProfileFilenameHere" action="release" version="1.0.2"

where you run the command from the path:

/dojo-release-1.0.2-src/util/buildscripts

Note that the entire built distribution directory tree needs to be included in your webapp, not just the built dojo.js and file described in the name build parameter below.

Note that it was not possible to fit the table within the fixed width of the light colored posting area. Simply select the table text to see it clearly.

Build Parameter		Function		Optional			If not provided, then:

dependencies		Container for layers	N if layers are provided.	Generates dojo.js base library.

layers			list of dojo libraries	N if dependencies are provided.	N/A
			to be built, where 
			each library is 
			stored in a separate 
			file			

name			path where layer is	N if dependencies are provided.	N/A
			to be stored. This
			path is relative to 
			the release/dojo/dojo 
			directory. Both a
			compressed (<name>.js) 
			and an uncompressed 
			(<name>.js.uncompressed.js) 
			module file will be 
			built. Name may only 
			contain a single dot and it
			must be just before the js
			file extension.

resourceName		string defining a	Y				No dojo.provide is included
			library; causes a 					in generated build file.
			dojo.provide to be 
			placed in the generated 
			build file where 
			resourceName is the 
			name you choose to 
			define your custom 
			built library. This
			name defines the
			namespace for the
			module to be 
			generated in the 
			given layer. (broken
			in versions 0.9 to 
			1.0.2 - see bug 5688)
							
layerDependencies	list of prebuilt dojo	Y				Assumes a dependency on dojo.js. 
			or custom libraries 					Generates dojo.js base library
			that libraries to be 					by default and copies it into the 
			generated depend upon					release directory.
						
dependencies		list of dojo widgets 	Y				No library beyond base libraries 
			to be built (baked) 					will be generated.
			into the generated 
			layer file defined by 
			the “name” parameter; 
			the dependencies are 
			those widgets that you 
			will request in your 
			web page(s) through 
			dojo.require statements

prefixes		list of dojo or custom 	Y				Modules are not copied to 
			directory paths where 					release directory.
			individual dojo modules 
			(for example individual 
			widget source files) 
			are stored. A module
			may reference other
			namespaces through
			dojo.require() 
			statements. The contents 
			of these directories are 
			copied to the release 
			directory during the 
			build sans any modules 
			included in the generated 
			base libraries or 
			libraries defined by the 
			“name” parameter

Path name is incorrect in 1.0.2

Hi.
Under the header "Creating a Custom Profile", the path name src/buildscripts/profiles should read utils/buildscripts/profiles.

Fixed

I've updated the page. Thanks :)

I don't have that directory in my dojo

--EDIT---
I found it, (i downloaded the src file) thanks anyway

I don't have buildscipts directory and build.sh. where I can find it?
Thanks

Building and using custom modules outside Dojo hierarchy

You might want to have your own modules outside dojo-hierarchy, so that they're not parallel to dojo, dijit and dojox, but instead one level up. To do this properly there are few things to remember. First, you probably want keep your modules totally separate from Dojo's, so let's set it to build your layer files into your module directory. When you change your layer-name to point to your module directory, layer-files (also uncompressed.js) and localization resources (nls-directory) will be copied there. See the following sample profile:

dependencies = {
  layers: [
    {
      name: "../../my/my-all.js",
      dependencies: [
        "my.Widget1"
        // ...
      ]
    }
  ],

  prefixes: [
    [ "dijit", "../dijit" ],
    [ "dojox", "../dojox" ],
    [ "my", "../../my" ]
  ]
};

Second, to use this from your pages, you need to include and set stuff in the correct order:

  1. dojo.js and djconfig - load the basic Dojo functionality
  2. registerModulePath - set the custom module namespace correctly
  3. my-all.js - load the layer file
  4. require - load the classes normally, if the layer wasn't found

See the following snippet:

<script type="text/javascript" src="/js/dojo-1.1.1/dojo/dojo.js"
djconfig="parseOnLoad: true, isDebug: true">
</script>

<script language="JavaScript" type="text/javascript">
  dojo.registerModulePath("my", "/js/my");
</script>

<script type="text/javascript" src="/js/my/my-all.js"></script>

<script language="JavaScript" type="text/javascript">
  dojo.require("my.Widget1");
  // ...
</script>

Including a Copyright in the Layer

If you wish to have a custom copyright included in the layer, you must add a copyrightFile to the layer specification. See the file util/layer.profile.js for an example. Note that this is the only copyright included in the layer, so if the layer bunches dojo dependencies with 'explosive' dependencies, then both copyrights would need to be included in the file specified by the copyrightFile property.

how much does it compress i

how much does it compress
i made a custom build but the compression was not so good.
can you tell what level of compression does it allow .......
my custom build for dojo 1.1.1 has a size of 9.04 mb ......... using optimize=packer
is there any option to further compress the file

Regards,
Prajot

1.1 megs is as small as I've gotten it

... that is, for a full working dojo source. You can of course limit it down to dojo.js + layer.js + nls/* for your layer:

http://www.sitepen.com/blog/2008/04/02/dojo-mini-optimization-tricks-wit...

(the build_mini script is available in trunk)

how to include all dependent files into a single JS file?

Is there a shorthanded way to include all dependent files into a single JS file without explicitly listing them in the "dependencies" section?

CSS Optimizations



To compress @imported css files into one file, you can also use the following option:

cssOptimize=comments.keepLines

Thanks for this info Pete!

Build system updates in Dojo 1.1

This piece of news was missing from the article: Dojo 1.1 supports the following new build options:

  • cssOptimize: cssOptimize=comments will strip comments and whitespace from CSS files and also inline any CSS files that are referenced by @import rules.
  • cssImportIgnore: cssImportIgnore takes a comma separated list of file paths. These file names will not be inlined during the cssOptimize step. The file paths used in cssImportIgnore should match the file paths used in the @import calls.
  • buildLayers: After you do a full build, if you just want to rebuild a layer or set of layers, you can pass buildLayers=[comma separated list of layer names], and just those layers will be rebuilt. If you have problems with the option, try doing a full build and trying again.
  • symbol: symbol=short and symbol=long will inject function names for all anonymous functions, making it easier to do some debugging in environments like IE.
  • There are new build options associated with multiversion support. See the Multiversion Book Page for more information.
  • Rhino builds: You can now do custom builds that target Rhino as the host environment, instead of the browser. See the example build file to see how to specify the Rhino host environment.

Build system updates in Dojo 1.2

Smaller build system changes also in Dojo 1.2. See Dojo 1.2 Loader and Build System highlights:

The final example in the slides demonstrates how you can create a 5.5 KB (gzipped) dojo.js file and dynamically load it after the page loads, so if your site uses progressive enhancement, your up-front Dojo cost can be zero bytes, and just load as little as possible for the functionality that you use.
...
There is a new build option for stripping out console method calls. stripConsole=normal strips out all console.* calls except console.error and console.warn. stripConsole=all strips all console.* calls.

Dependency tracking and aggregation

Let me say that custom builds architecture and implementation are beautiful and absolutely great from the engineering point!

In particular, the use of full-blown parsing (Rhino) for compression (instead of regexes) makes it a really solid solution.

I would like the clarification on how layer dependencies are tracked and aggregated in current implementation. I see that build process tracks at least MOST module dependencies inside dojo tree for their aggregation into layer, so the number of requests are reduced dramatically and performance is high. But does layer reliably track and include ALL dependencies? Is that possible that some required module is not included into layer despite layer depends on that module -- lets call it "layer dependency leak".

In other words, if widgetry uses only, say, 300KB layer, nls bundles, and dofo.js, is it safe to remove the unused rest of ~3MB of dojo library leaving only that layer, nls and dojo.js? (At production site, not development, of course.)

Since layer is supposed to live in (be complemented with) the rest of the dojo library, the dependency leak in a layer is not critical - leaked module is readily available in dojo library. Thus, the rest of the library acts like a safety net against layer dependency leaks. But if layer dependency tracking&aggregation is complete and reliable (as compression is), such safety net is not needed and rest of the library can be removed.

My working assumption is that it is not safe to remove rest of the library.

It would be nice to hear expert opinion on this.

Consider images in themes folder

If the layer file is complete, there are no "leaks" and the rest (excluding nls) can be removed. Unless, of course, you're using dijit (or your own) themes that load images from dijit/themes/[...]/images. But why would you want to do that? If you're concerned about the original files being in plain-text, just set optimize parameter for the build and these files will be minimized ("obfuscated") as well.

My concern is very similar

My concern is very similar to that addressed by custom build system in the first place -- performance and number of requests, but this time the number of requests in the dojo library deployment process. In development I use some scripted automation to make custom build of dojo library and then automatically deploy it on the production server. The need to deploy entire library, including numerous files that my widgetry never use, makes deployment (upload) process very slow. If I know for sure, that layer file (and nls and themes) includes ALL (not MOST) that my widgetry uses, then I can deploy only a handful of files -- only those that are really used, speeding deployment more than 10 times.

Another concern (potentially relevant) is to reduce the footprint on the disk. This is not directly relevant in my case but I can imagine that it may well be a concern for some potential uses of dojo library.

Regardless of my case, I think, in general, using custom layers may not only increase performance (which is the major goal, of course), but also ease building and deploying dojo applications.

Currently, it seems that my custom layer interns all dependencies and it is likely that I can remove (omit from deployment) the rest of the library. (And yes, the themes directory needs to be in place, thanks for the tip!) But it is something that cannot be tested for sure. That is why I am still researching this issue.

May be I miss something, but, for example, the following minor conditional dependency buried in some dojo module is hard to automatically detect by the custom build process (unless author declares that somehow):

if (some_run_time_condition) { dojo.require(foo+bar) }

What do you think?

Conditional dependencies

Conditional dependencies in your sample will always get included in the layer file. This is because the build tool uses regexp to spot dependencies. However, conditional dependencies done using requireIf would cause some problems, if the originals were deleted. But I'd say that if you declare it like that, you must take care not to delete the file.

Whether it is worth doing all of this, I'd say no. As long as we're talking about web server environment, few extra MBs on the server mean nothing, and reducing upload size from MBs to KBs is just few minutes of transfer time (when you transfer it zipped, not file-by-file). If you want to optimize it for Flash/AIR, it's a different story, and you might find this article interesting: Dojo-Mini: Optimization Tricks with the Dojo Toolkit.

Conditional dependency

Maine, thank you very much, your comments are very useful!

I've already read that "Dojo-Mini: Optimization Tricks with the Dojo Toolkit" post. Yes, I find it interesting. But I find it to be sort of a hackery (tricks) that work only sometimes (and it is unknown whether they will work for sure). The story is full of guesswork, so its real value is questionable. The right way, I think, is simply using full power of layer system (it is what layers are for, actually). Layer can be seen as essentially a way to isolate the subset of dojo library used by application. If layer has no dependency leaks (!), then leaving layer, nls, themes, and dojo.js and simply nothing more beyond that will do a perfect optimization for just anything. Anything else in dojo library is simply not used by application and can be safely removed without any guesswork. But now it looks like it cannot be safely removed.

It seems that I myself have now witnessed (with Firebug) how my widgetry sometimes (!) do request dojo modules beyond layer. And since it happens only sometimes, I cannot easily test for it, since for any non-trivial widgetry it is not feasible to test all execution paths. So, chances are that user, not developer, will be the first who discover errors on the page, if I remove rest of the dojo library.

Back to my sample above: Conditional dependency in my sample will not be included into layer, since dojo.require() in my sample has expression as its argument, so the regex used by build tool will, of course, fail to spot it. Plus, you mentioned another case when that regex will, of course, fail - dogo.requireIf(). Can it be that some dojo module has such sort of dependency, which regex fails to spot, so that including such module into layer will introduce a dependency leak? I mean dojo library modules, not my modules (since I know my modules well and can easily work around such things in them, but not in dojo modules). I think it can happen easily, since conditional dojo.requireIf() as well expression arguments to dojo.require() are a natural thing that can be expected to be used here and there in modules of dojo library. And such dependencies will not be spotted by custom build system - at least the regex you mention cannot do this. This means we should expect layers to be incomplete.

access is denied javascript error ie6

I did a custom dojo build on the 1.3 src and loaded both js in my jsp page

dojo.js
mydojo.js

it works fine, but in IE6 it shows Access is denied javascript error.
Firefox error console doesn't show any errors

anyone know of a fix for this? thanks~

the profile i used...

dependencies ={
layers: [
{
name: "mydojo.js",
dependencies: [
"dojox.grid.DataGrid",
"dojo.data.ItemFileReadStore"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ]
]
};

NOTE:
I tried doing a custom build with 1.2.3 src with the same exact profile and it works fine with NO 'access is denied' javascript error.

Cross-domain build?

Cross-domain build? There's a bug in DataGrid that breaks it in cross-domain builds. It's fixed in 1.3.1.

Minimizing Dojo builds (more resources)

Still few more notes about minimizing Dojo builds... There's a video over DojoCampus Dojo Build 301: Compacting your build that demonstrates briefly howto build minimized Dojo package. There have been some changes from 1.2 to 1.3 that are best explained by this snippet from build_mini:

build_mini.sh is available in the official Dojo release 1.2!

If you are using 1.2.x, use build_mini.sh from the official repository:

In Dojo 1.3 and higher, build_mini.sh was removed and replaced with:

  • build parameters mini="true" and copyTests="false"
  • a post-build script named clean_release.sh (also available in 1.2), which does the same work as build_mini, though requires you run a standard build prior.

A port of the original mini script to work with 1.2.3 is available here and was contributed by Sudheer.