| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
| <html> |
| <head> |
| <!-- Begin Header -->
|
| <title>Gitblit</title>
|
| <meta charset="utf-8">
|
| <meta name="ROBOTS" content="INDEX">
|
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
| <link rel="stylesheet" href="./bootstrap/css/bootstrap.css"> |
| <link rel='shortcut icon' type='image/png' href='./gitblt-favicon.png' /> |
| <link rel="stylesheet" href="./prettify/prettify.css" /> |
| <!-- Google Plus Profile Page -->
|
| <link rel="publisher" href="https://plus.google.com/114464678392593421684" />
|
| <style type="text/css"> a.gpluspage { margin-top:3px;text-decoration: none; } </style> |
| |
| <!-- Google Plus One -->
|
| <link rel="canonical" href="http://gitblit.com" />
|
| <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
|
| <style type="text/css"> div.gplusone { margin-top:12px; } </style> |
| |
| <script src="./prettify/prettify.js"></script> |
| <script src="./bootstrap/js/jquery.js"></script> |
| <script src="./bootstrap/js/bootstrap.min.js"></script> |
| </head> |
| <body onload='prettyPrint()'> <!-- Navigation Bar -->
|
| <div class="navbar navbar-fixed-top">
|
| <div class="navbar-inner">
|
| <div class="container">
|
| <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
| <span class="icon-bar"></span>
|
| <span class="icon-bar"></span>
|
| <span class="icon-bar"></span>
|
| </a>
|
| <a class="brand" href="./"><img src="./gitblt_25_white.png" alt="Gitblit"></img></a>
|
| <div class="nav-collapse">
|
| <ul class="nav">
|
| <li class='dropdown'> <!-- Menu --> |
| <a class='dropdown-toggle' href='#' data-toggle='dropdown'>about<b class='caret'></b></a> |
| <ul class='dropdown-menu'> |
| <li><a href='index.html'>overview</a></li> |
| <li><a href='features.html'>features</a></li> |
| <li><a href='screenshots.html'>screenshots</a></li> |
| </ul></li> <!-- End Menu --> |
| <li class='dropdown'> <!-- Menu --> |
| <a class='dropdown-toggle' href='#' data-toggle='dropdown'>documentation<b class='caret'></b></a> |
| <ul class='dropdown-menu'> |
| <li class='dropdown-submenu'> <!-- Submenu --> |
| <a tabindex='-1' href='#'>Gitblit GO</a> |
| <ul class='dropdown-menu'> |
| <li><a href='setup_go.html'>setup GO</a></li> |
| <li><a href='upgrade_go.html'>upgrade GO</a></li> |
| </ul></li> <!-- End Submenu --> |
| <li class='divider'></li> |
| <li class='dropdown-submenu'> <!-- Submenu --> |
| <a tabindex='-1' href='#'>Gitblit WAR</a> |
| <ul class='dropdown-menu'> |
| <li><a href='setup_war.html'>setup WAR</a></li> |
| <li><a href='upgrade_war.html'>upgrade WAR</a></li> |
| </ul></li> <!-- End Submenu --> |
| <li class='divider'></li> |
| <li class='dropdown-submenu'> <!-- Submenu --> |
| <a tabindex='-1' href='#'>Server Configuration</a> |
| <ul class='dropdown-menu'> |
| <li><a href='administration.html'>administration</a></li> |
| <li><a href='setup_authentication.html'>authentication</a></li> |
| <li><a href='setup_hooks.html'>push hooks</a></li> |
| <li><a href='setup_lucene.html'>lucene indexing</a></li> |
| <li><a href='setup_proxy.html'>reverse proxies</a></li> |
| <li><a href='setup_clientmenus.html'>client app menus</a></li> |
| <li><a href='setup_bugtraq.html'>bugtraq</a></li> |
| <li><a href='setup_mirrors.html'>mirrors</a></li> |
| <li><a href='setup_scaling.html'>scaling</a></li> |
| <li class='divider'></li> |
| <li><a href='setup_viewer.html'>Gitblit as a viewer</a></li> |
| </ul></li> <!-- End Submenu --> |
| <li class='divider'></li> |
| <li class='dropdown-submenu'> <!-- Submenu --> |
| <a tabindex='-1' href='#'>Client Usage</a> |
| <ul class='dropdown-menu'> |
| <li><a href='setup_transport_http.html'>using HTTP/HTTPS</a></li> |
| <li><a href='setup_transport_ssh.html'>using SSH</a></li> |
| <li><a href='eclipse_plugin.html'>using the Eclipse plugin</a></li> |
| </ul></li> <!-- End Submenu --> |
| <li class='divider'></li> |
| <li class='dropdown-submenu'> <!-- Submenu --> |
| <a tabindex='-1' href='#'>Tickets</a> |
| <ul class='dropdown-menu'> |
| <li><a href='tickets_overview.html'>overview</a></li> |
| <li><a href='tickets_using.html'>using</a></li> |
| <li><a href='tickets_barnum.html'>barnum</a></li> |
| <li><a href='tickets_setup.html'>setup</a></li> |
| <li><a href='tickets_replication.html'>replication & advanced administration</a></li> |
| </ul></li> <!-- End Submenu --> |
| <li class='divider'></li> |
| <li class='dropdown-submenu'> <!-- Submenu --> |
| <a tabindex='-1' href='#'>Plugins</a> |
| <ul class='dropdown-menu'> |
| <li><a href='plugins_overview.html'>overview</a></li> |
| <li><a href='plugins_extensions.html'>extension points</a></li> |
| </ul></li> <!-- End Submenu --> |
| <li class='divider'></li> |
| <li><a href='federation.html'>federation</a></li> |
| <li class='divider'></li> |
| <li><a href='properties.html'>settings</a></li> |
| <li><a href='faq.html'>faq</a></li> |
| <li class='divider'></li> |
| <li><a href='design.html'>design</a></li> |
| <li><a href='rpc.html'>rpc</a></li> |
| </ul></li> <!-- End Menu --> |
| <li class='dropdown'> <!-- Menu --> |
| <a class='dropdown-toggle' href='#' data-toggle='dropdown'>releases<b class='caret'></b></a> |
| <ul class='dropdown-menu'> |
| <li><a href='releasenotes.html'>release notes</a></li> |
| <li><a href='releases.html'>release history</a></li> |
| <li class='divider'></li> |
| <li><a href='roadmap.html'>roadmap</a></li> |
| </ul></li> <!-- End Menu --> |
| <li class='dropdown'> <!-- Menu --> |
| <a class='dropdown-toggle' href='#' data-toggle='dropdown'>downloads<b class='caret'></b></a> |
| <ul class='dropdown-menu'> |
| <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.2.zip'>Gitblit GO (Windows)</a></li> |
| <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.2.tar.gz'>Gitblit GO (Linux/OSX)</a></li> |
| <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.2.war'>Gitblit WAR</a></li> |
| <li class='divider'></li> |
| <li><a href='https://registry.hub.docker.com/u/jmoger/gitblit/'>Gitblit GO (Docker)</a></li> |
| <li class='divider'></li> |
| <li><a href='http://plugins.gitblit.com'>Plugins Registry</a></li> |
| <li class='divider'></li> |
| <li><a href='http://dl.bintray.com/gitblit/releases/manager-1.6.2.zip'>Gitblit Manager</a></li> |
| <li><a href='http://dl.bintray.com/gitblit/releases/fedclient-1.6.2.zip'>Federation Client</a></li> |
| <li class='divider'></li> |
| <li><a href='http://dl.bintray.com/gitblit/releases/gbapi-1.6.2.zip'>API Library</a></li> |
| <li class='divider'></li> |
| <li><a href='https://bintray.com/gitblit/releases/gitblit'>Bintray (1.4.0+)</a></li> |
| <li><a href='https://code.google.com/p/gitblit/downloads/list?can=1'>GoogleCode (pre-1.4.0)</a></li> |
| <li class='divider'></li> |
| <li><a href='http://gitblit.github.io/gitblit-maven'>Maven Repository</a></li> |
| </ul></li> <!-- End Menu --> |
| <li class='dropdown'> <!-- Menu --> |
| <a class='dropdown-toggle' href='#' data-toggle='dropdown'>links<b class='caret'></b></a> |
| <ul class='dropdown-menu'> |
| <li><a href='https://dev.gitblit.com'>dev.gitblit.com (self-hosted)</a></li> |
| <li class='divider'></li> |
| <li><a href='http://plugins.gitblit.com'>Plugins Registry</a></li> |
| <li class='divider'></li> |
| <li><a href='https://github.com/gitblit/gitblit'>Github</a></li> |
| <li><a href='http://code.google.com/p/gitblit/issues/list'>Issues</a></li> |
| <li><a href='http://groups.google.com/group/gitblit'>Discussion</a></li> |
| <li><a href='https://plus.google.com/114464678392593421684'>Google+</a></li> |
| <li><a href='https://twitter.com/gitblit'>Twitter</a></li> |
| <li><a href='http://www.ohloh.net/p/gitblit'>Ohloh</a></li> |
| <li class='divider'></li> |
| <li><a href='https://vimeo.com/86164723'>Gitblit Tickets screencast</a></li> |
| <li><a href='https://asciinema.org/a/9342'>Gitblit SSH and Plugin Management asciicast</a></li> |
| <li><a href='http://episodes.gitminutes.com/2014/05/gitminutes-29-james-moger-on-gitblit.html'>GitMinutes #29: James Moger on Gitblit</a></li> |
| <li class='divider'></li> |
| <li><a href='https://plus.google.com/+JamesMoger'>+JamesMoger</a></li> |
| <li><a href='https://twitter.com/JamesMoger'>@JamesMoger</a></li> |
| </ul></li> <!-- End Menu --> |
| <li class='divider-vertical'></li> |
| <li><a href='https://plus.google.com/114464678392593421684?prsrc=3' class='gpluspage'><img src='https://ssl.gstatic.com/images/icons/gplus-16.png' width='16' height='16 style='order: 0;'/></a></li><li><div class='gplusone'><g:plusone size='small' href='http://gitblit.com'></g:plusone></div></li>
|
| </ul>
|
| </div><!--/.nav-collapse -->
|
| </div>
|
| </div>
|
| </div><!-- end Navigation Bar --> |
| <div class='container'> |
| <!-- Begin Markdown --> |
| <h2 class="section" id='H1'><a href="#H1" class="sectionlink"><i class="icon-share-alt"> </i></a>Extension Points</h2><p>Gitblit offers several extension points for enhancing and customizing it's runtime behavior.</p><p>Each available extension point has a sample implementation in the <a href="https://github.com/gitblit/gitblit-cookbook-plugin">gitblit-cookbook-plugin (Maven project)</a>.</p><p><strong>NOTE:</strong><br/>Gitblit does not yet offer a comprehensize dependency injection architecture. This will be addressed in a subsequent release. For now you may access all of Gitblit's core managers through a static singleton app context:</p><p><pre>import com.gitblit.extensions.GitblitPlugin; |
| import com.gitblit.servlet.GitblitContext; |
| import com.gitblit.manager.IRuntimeManager; |
| import com.gitblit.manager.IUserManager; |
| import com.gitblit.manager.IAuthenticationManager; |
| import com.gitblit.manager.INotificationManager; |
| import com.gitblit.manager.IRepositoryManager; |
| import com.gitblit.manager.IProjectManager; |
| import com.gitblit.manager.IFederationManager; |
| import com.gitblit.manager.IPluginManager; |
| import com.gitblit.manager.IGitblit; |
| import ro.fortsoft.pf4j.Version; |
| |
| public class ExamplePlugin extends GitblitPlugin { |
| |
| @Override |
| public void start() { |
| IRuntimeManager runtime = GitblitContext.getManager(IRuntimeManager.class); |
| IUserManager users = GitblitContext.getManager(IUserManager.class); |
| IAuthenticationManager auth = GitblitContext.getManager(IAuthenticationManager.class); |
| INotificationManager notifications = GitblitContext.getManager(INotificationManager.class); |
| IRepositoryManager repos = GitblitContext.getManager(IRepositoryManager.class); |
| IProjectManager projects = GitblitContext.getManager(IProjectManager.class); |
| IFederationManager federation = GitblitContext.getManager(IFederationManager.class); |
| IPluginManager plugins = GitblitContext.getManager(IPluginManager.class); |
| IGitblit gitblit = GitblitContext.getManager(IGitblit.class); |
| } |
| |
| @Override |
| public void stop() { |
| } |
| |
| @Override |
| public void onInstall() { |
| } |
| |
| @Override |
| public void onUpgrade(Version oldVersion) { |
| } |
| |
| @Override |
| public void onUninstall() { |
| } |
| } |
| |
| /** |
| * You can also create Webapp plugins that register pages. |
| */ |
| public class ExampleWicketPlugin extends GitblitWicketPlugin { |
| @Override |
| public void start() { |
| } |
| |
| @Override |
| public void stop() { |
| } |
| |
| @Override |
| public void onInstall() { |
| } |
| |
| @Override |
| public void onUpgrade(Version oldVersion) { |
| } |
| |
| @Override |
| public void onUninstall() { |
| } |
| |
| @Override |
| protected void init(GitblitWicketApp app) { |
| app.mount("/logo", LogoPage.class); |
| app.mount("/hello", HelloWorldPage.class); |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H2'><a href="#H2" class="sectionlink"><i class="icon-share-alt"> </i></a>SSH Dispatch Command</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom SSH command hierarchies by subclassing the <em>DispatchCommand</em> class.</p><p><pre>import ro.fortsoft.pf4j.Extension; |
| import org.kohsuke.args4j.Option; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import com.gitblit.transport.ssh.commands.CommandMetaData; |
| import com.gitblit.transport.ssh.commands.DispatchCommand; |
| import com.gitblit.transport.ssh.commands.UsageExample; |
| |
| @Extension |
| @CommandMetaData(name = "mycommands", description = "Sample SSH dispatcher") |
| public class MyDispatcher extends DispatchCommand { |
| |
| @Override |
| protected void setup() { |
| // commands in this dispatcher |
| register(CommandA.class); |
| register(CommandB.class); |
| |
| // nested dispatchers |
| register(SubDispatcher1.class); |
| register(SubDispatcher2.class); |
| } |
| |
| @CommandMetaData(name = "commanda", aliases = { "ca" }, description = "description of command a") |
| @UsageExample(syntax = "${cmd} --myflag", description = "description of commanda with --myflag") |
| public static class CommandA extends SshCommand { |
| |
| protected final Logger log = LoggerFactory.getLogger(getClass()); |
| |
| @Option(name = "--myflag", aliases = { "-m" }, usage = "enable myflag") |
| boolean myflag; |
| |
| @Override |
| public void run() throws Failure { |
| if (myflag) { |
| log.info("Run with --myflag"); |
| } else { |
| log.info("Run without --myflag"); |
| } |
| } |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H3'><a href="#H3" class="sectionlink"><i class="icon-share-alt"> </i></a>Pre- and Post- Receive Hook</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom pre and/or post receive hooks by subclassing the <em>ReceiveHook</em> class.</p><p><pre>import com.gitblit.extensions.ReceiveHook; |
| import java.util.Collection; |
| import org.eclipse.jgit.transport.ReceiveCommand; |
| import ro.fortsoft.pf4j.Extension; |
| |
| @Extension |
| public class MyReceiveHook extends ReceiveHook { |
| |
| @Override |
| public void onPreReceive(GitblitReceivePack receivePack, Collection<ReceiveCommand> commands) { |
| } |
| |
| @Override |
| public void onPostReceive(GitblitReceivePack receivePack, Collection<ReceiveCommand> commands) { |
| } |
| } |
| |
| </pre></p> |
| <h3 class="section" id='H4'><a href="#H4" class="sectionlink"><i class="icon-share-alt"> </i></a>Patchset Hook</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom patchset hook by subclassing the <em>PatchsetHook</em> class.</p><p><pre>import com.gitblit.extensions.PatchsetHook; |
| import com.gitblit.models.TicketModel; |
| import ro.fortsoft.pf4j.Extension; |
| |
| @Extension |
| public class MyPatchsetHook extends PatchsetHook { |
| |
| @Override |
| public void onNewPatchset(TicketModel ticket) { |
| } |
| |
| @Override |
| public void onUpdatePatchset(TicketModel ticket) { |
| } |
| |
| @Override |
| public void onMergePatchset(TicketModel ticket) { |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H5'><a href="#H5" class="sectionlink"><i class="icon-share-alt"> </i></a>Ticket Hook</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom ticket hook by subclassing the <em>TicketHook</em> class.</p><p><pre>import com.gitblit.extensions.TicketHook; |
| import com.gitblit.models.TicketModel; |
| import com.gitblit.models.TicketModel.Change; |
| import ro.fortsoft.pf4j.Extension; |
| |
| @Extension |
| public class MyTicketHook extends TicketHook { |
| |
| @Override |
| public void onNewTicket(TicketModel ticket) { |
| } |
| |
| @Override |
| public void onUpdateTicket(TicketModel ticket, Change change) { |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H6'><a href="#H6" class="sectionlink"><i class="icon-share-alt"> </i></a>Request Filter</h3><p><em>SINCE 1.6.0</em></p><p>You can provide your own custom request filter by subclassing the <em>HttpRequestFilter</em> class.</p><p><pre>import com.gitblit.extensions.HttpRequestFilter; |
| import ro.fortsoft.pf4j.Extension; |
| |
| @Extension |
| public class MyRequestFilter extends HttpRequestFilter { |
| |
| @Override |
| public void doFilter(ServletRequest request, ServletResponse response, |
| FilterChain chain) throws IOException, ServletException { |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H7'><a href="#H7" class="sectionlink"><i class="icon-share-alt"> </i></a>User Menu Items</h3><p><em>SINCE 1.6.0</em></p><p>You can provide your own user menu items by subclassing the <em>UserMenuExtension</em> class.</p><p><pre>import java.util.Arrays; |
| import java.util.List; |
| import ro.fortsoft.pf4j.Extension; |
| import com.gitblit.extensions.UserMenuExtension; |
| import com.gitblit.models.Menu.ExternalLinkMenuItem; |
| import com.gitblit.models.Menu.MenuItem; |
| import com.gitblit.models.UserModel; |
| |
| @Extension |
| public class MyUserMenuContributor extends UserMenuExtension { |
| |
| @Override |
| public List<MenuItem> getMenuItems(UserModel user) { |
| MenuItem item = new ExternalLinkMenuItem("Github", String.format("https://github.com/%s", user.username)); |
| return Arrays.asList(item); |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H8'><a href="#H8" class="sectionlink"><i class="icon-share-alt"> </i></a>Navigation Links</h3><p><em>SINCE 1.6.0</em></p><p>You can provide your own top-level navigation links by subclassing the <em>NavLinkExtension</em> class.</p><p><pre>import java.util.Arrays; |
| import java.util.List; |
| import ro.fortsoft.pf4j.Extension; |
| import com.gitblit.extensions.NavLinkExtension; |
| import com.gitblit.models.UserModel; |
| |
| @Extension |
| public class MyNavLink extends NavLinkExtension { |
| |
| @Override |
| public List<NavLink> getNavLinks(UserModel user) { |
| NavLink link = new ExternalLinkMenuItem("Github", String.format("https://github.com/%s", user.username)); |
| return Arrays.asList(link); |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H9'><a href="#H9" class="sectionlink"><i class="icon-share-alt"> </i></a>Server Lifecycle Listener</h3><p><em>SINCE 1.6.0</em></p><p>You can provide a lifecycle listener to be notified when Gitblit has completely started and just before Gitblit is gracefully terminated.</p><p><pre>import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import ro.fortsoft.pf4j.Extension; |
| import com.gitblit.extensions.LifeCycleListener; |
| |
| @Extension |
| public class MyLifeCycleListener extends LifeCycleListener { |
| |
| final Logger log = LoggerFactory.getLogger(getClass()); |
| |
| @Override |
| public void onStartup() { |
| log.info("Gitblit is Ready!!"); |
| } |
| |
| @Override |
| public void onShutdown() { |
| log.info("Gitblit is Going Down!!"); |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H10'><a href="#H10" class="sectionlink"><i class="icon-share-alt"> </i></a>Repository Lifecycle Listener</h3><p><em>SINCE 1.6.0</em></p><p>You can provide a lifecycle listener to be notified when Gitblit has created or deleted a repository.</p><p><pre>import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import ro.fortsoft.pf4j.Extension; |
| import com.gitblit.extensions.RepositoryLifeCycleListener; |
| import com.gitblit.models.RepositoryModel; |
| |
| @Extension |
| public class MyRepoLifeCycleListener extends RepositoryLifeCycleListener { |
| |
| final Logger log = LoggerFactory.getLogger(getClass()); |
| |
| @Override |
| public void onCreation(RepositoryModel repo) { |
| log.info("Gitblit created {}", repo); |
| } |
| |
| @Override |
| public void onDeletion(RepositoryModel repo) { |
| log.info("Gitblit deleted {}", repo); |
| } |
| } |
| </pre></p> |
| <h3 class="section" id='H11'><a href="#H11" class="sectionlink"><i class="icon-share-alt"> </i></a>User/Team Lifecycle Listener</h3><p><em>SINCE 1.6.0</em></p><p>You can provide a lifecycle listener to be notified when Gitblit has created or deleted a user or a team.</p><p><pre>import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import ro.fortsoft.pf4j.Extension; |
| import com.gitblit.extensions.UserTeamLifeCycleListener; |
| import com.gitblit.models.TeamModel; |
| import com.gitblit.models.UserModel; |
| |
| @Extension |
| public class MyUserTeamLifeCycleListener extends UserTeamLifeCycleListener { |
| |
| final Logger log = LoggerFactory.getLogger(getClass()); |
| |
| @Override |
| public void onCreation(UserModel user) { |
| log.info("Gitblit created user {}", user); |
| } |
| |
| @Override |
| public void onDeletion(UserModel user) { |
| log.info("Gitblit deleted user {}", user); |
| } |
| |
| @Override |
| public void onCreation(TeamModel team) { |
| log.info("Gitblit created team {}", team); |
| } |
| |
| @Override |
| public void onDeletion(TeamModel team) { |
| log.info("Gitblit deleted team {}", team); |
| } |
| } |
| </pre> |
| <!-- End Markdown --> |
| <div ><ul class="pager"><li class="previous"><a href="plugins_overview.html">← overview</a></li> </ul></div><footer class="footer"><p class="pull-right">generated 2014-10-28</p>
|
| <p>The content of this page is licensed under the <a href="http://creativecommons.org/licenses/by/3.0">Creative Commons Attribution 3.0 License</a>.</p> |
| </footer> |
| </div> |
| <!-- Google Analytics -->
|
| <script type="text/javascript">
|
| var _gaq = _gaq || [];
|
| _gaq.push(['_setAccount', 'UA-24377072-1']);
|
| _gaq.push(['_trackPageview']);
|
|
|
| (function() {
|
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
| })();
|
| </script> |
| |
| </body> |
| </html> |