Merge commit 'refs/pull/583/head' of github.com:apache/usergrid
diff --git a/content/index.html b/content/index.html
index 0394438..83803f0 100644
--- a/content/index.html
+++ b/content/index.html
@@ -78,8 +78,8 @@
             </div>
 
             <div class="btn-wrapper">
-                <iframe class="social-btn" src="/static/github-btn.html?user=apache&repo=usergrid&type=watch&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
-                <iframe class="social-btn" src="/static/github-btn.html?user=apache&repo=usergrid&type=fork&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
+                <iframe class="social-btn" src="https://ghbtns.com/github-btn.html?user=apache&repo=usergrid&type=watch&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
+                <iframe class="social-btn" src="https://ghbtns.com/github-btn.html?user=apache&repo=usergrid&type=fork&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
                 <!--<p><span class="or">or</span> <a href="#">Download Usergrid</a></p>-->
             </div>
 
diff --git a/content/releases/index.html b/content/releases/index.html
index beb5bca..2c71570 100644
--- a/content/releases/index.html
+++ b/content/releases/index.html
@@ -98,6 +98,7 @@
 					Project releases are approved by vote of the Apache Usergrid Project Management Committee (PMC). Support for a release is provided by project volunteers on the project <a href="http://usergrid.apache.org/community/#mailing-lists">mailing lists</a>. Bugs found in a release may be discussed on the list and reported through the <a href="https://issues.apache.org/jira/browse/USERGRID">issue tracker</a>. The user mailing list and issue tracker are the only support options hosted by the Apache Usergrid project.
 				</p>
 				<p>
+
 					Note: When downloading from a mirror, please be sure to verify that checksums and signatures are correct. To do so, use the checksum and signature files from the main Apache site at <a href="https://www.apache.org/dist/usergrid/usergrid-2/v2.1.0/">https://dist.apache.org/repos/dist/release/usergrid/usergrid-2/v2.1.0/</a>. Find here the KEYS file, which contains all OpenPGP keys we use to sign releases here: <a href="https://www.apache.org/dist/usergrid/KEYS">https://www.apache.org/dist/usergrid/KEYS</a>
 				</p>
 				<p>
diff --git a/docs/README.md b/docs/README.md
index 2f7888c..27a8baf 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -6,8 +6,8 @@
 
 Sphinx requires Python and pip. Once you have Python, you can install sphinx and pip like so:
 
-	$ sudo easy_install sphinx
 	$ sudo easy_install pip
+	$ sudo pip install sphinx==1.3.2
 
 ## How to build the Usergrid documentation using Sphinx
 
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/traverse/EntityLoadVerifyFilter.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/traverse/EntityLoadVerifyFilter.java
index cc82bd8..c6a3462 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/traverse/EntityLoadVerifyFilter.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/traverse/EntityLoadVerifyFilter.java
@@ -167,6 +167,7 @@
 
                 int edgesDeleted = 0;
                 List<MarkedEdge> edgeList = graphManager.loadEdgeVersions(searchByEdge).toList().toBlocking().last();
+                boolean timestampAllowsDelete = false;
                 if (edgeList.size() > 0) {
                     MarkedEdge firstEdge = edgeList.get(0);
                     long currentTimestamp = CpNamingUtils.createGraphOperationTimestamp();
@@ -176,6 +177,7 @@
                     // timestamps are in 100 nanoseconds, convert from seconds
                     long allowedDiff = orphanDelaySecs * 1000L * 1000L * 10L;
                     if (timestampDiff > allowedDiff) {
+                        timestampAllowsDelete = true;
                         // edges must be orphans, delete edges
                         for (MarkedEdge edge: edgeList) {
                             graphManager.markEdge(edge).toBlocking().lastOrDefault(null);
@@ -188,6 +190,14 @@
                 if (edgesDeleted > 0) {
                     logger.warn("Read graph edge and received candidate with entityId {} (application {}), yet was not found in cassandra."
                         + "  Deleted at least {} edges.", candidateId, applicationScope.getApplication().getUuid().toString(), edgesDeleted);
+                } else if (edgeList.size() == 0) {
+                    logger.warn("Read graph edge and received candidate with entityId {} (application {}), yet was not found in cassandra."
+                            + "  No edges were deleted (loadEdgeVersions returned 0 edges)",
+                        candidateId, applicationScope.getApplication().getUuid().toString());
+                } else if (timestampAllowsDelete) {
+                    logger.warn("Read graph edge and received candidate with entityId {} (application {}), yet was not found in cassandra."
+                        + "  Timestamp is old enough to delete, but no edges were deleted (loadEdgeVersions returned {} edges)",
+                        candidateId, applicationScope.getApplication().getUuid().toString(), edgeList.size());
                 } else {
                     logger.warn("Read graph edge and received candidate with entityId {} (application {}), yet was not found in cassandra."
                         + "  Ignoring since this could be a region sync issue", candidateId, applicationScope.getApplication().getUuid().toString());
diff --git a/stack/tools/src/main/java/org/apache/usergrid/tools/EntityVersionAudit.java b/stack/tools/src/main/java/org/apache/usergrid/tools/EntityVersionAudit.java
new file mode 100644
index 0000000..ee064bc
--- /dev/null
+++ b/stack/tools/src/main/java/org/apache/usergrid/tools/EntityVersionAudit.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.usergrid.tools;
+
+
+import com.google.common.base.Optional;
+import com.netflix.astyanax.MutationBatch;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.usergrid.corepersistence.index.IndexLocationStrategyFactory;
+import org.apache.usergrid.corepersistence.service.CollectionService;
+import org.apache.usergrid.corepersistence.util.CpNamingUtils;
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.EntityRef;
+import org.apache.usergrid.persistence.Query;
+import org.apache.usergrid.persistence.SimpleEntityRef;
+import org.apache.usergrid.persistence.collection.EntityCollectionManager;
+import org.apache.usergrid.persistence.collection.EntityCollectionManagerFactory;
+import org.apache.usergrid.persistence.collection.MvccLogEntry;
+import org.apache.usergrid.persistence.core.scope.ApplicationScope;
+import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
+import org.apache.usergrid.persistence.graph.GraphManager;
+import org.apache.usergrid.persistence.graph.GraphManagerFactory;
+import org.apache.usergrid.persistence.graph.SearchByEdgeType;
+import org.apache.usergrid.persistence.graph.impl.SimpleEdge;
+import org.apache.usergrid.persistence.graph.impl.SimpleSearchByEdgeType;
+import org.apache.usergrid.persistence.graph.serialization.EdgeSerialization;
+import org.apache.usergrid.persistence.index.IndexLocationStrategy;
+import org.apache.usergrid.persistence.index.SearchEdge;
+import org.apache.usergrid.persistence.index.impl.EsProvider;
+import org.apache.usergrid.persistence.index.utils.UUIDUtils;
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+import org.apache.usergrid.persistence.schema.CollectionInfo;
+import org.apache.usergrid.utils.InflectionUtils;
+import org.elasticsearch.action.get.GetRequest;
+import org.elasticsearch.action.get.GetResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import rx.Observable;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.usergrid.corepersistence.util.CpNamingUtils.createSearchEdgeFromSource;
+import static org.apache.usergrid.persistence.Schema.getDefaultSchema;
+import static org.apache.usergrid.persistence.index.impl.IndexingUtils.createIndexDocId;
+
+
+public class EntityVersionAudit extends ToolBase {
+
+    /*
+
+        Writes to files in the current directory:
+            entity_es_urls.txt (contains the relative URLs for the elasticsearch API to GET a document for an entity and version
+            entity_version_agg.txt ( contains the number of versions per entity on a line)
+     */
+
+    private static final Logger logger = LoggerFactory.getLogger( EntityVersionAudit.class );
+
+    private static final String APPLICATION_ARG = "app";
+
+    private static final String ENTITY_TYPE_ARG = "entityType";
+
+    private static final String USE_LATEST_VERSION_ARG = "useLatestVersion";
+
+    private static final String ENTITY_UUID = "entityUUID";
+
+
+    private EntityManager em;
+
+    @Override
+    @SuppressWarnings( "static-access" )
+    public Options createOptions() {
+
+
+        Options options = super.createOptions();
+
+
+        Option appOption = OptionBuilder.withArgName( APPLICATION_ARG ).hasArg().isRequired( true )
+            .withDescription( "application id" ).create( APPLICATION_ARG );
+
+
+        options.addOption( appOption );
+
+        Option collectionOption =
+                OptionBuilder.withArgName(ENTITY_TYPE_ARG).hasArg().isRequired( true ).withDescription( "singular collection name" )
+                        .create(ENTITY_TYPE_ARG);
+
+        options.addOption( collectionOption );
+
+
+        Option useLatestVersion =
+            OptionBuilder.withArgName(USE_LATEST_VERSION_ARG).hasArg().isRequired( false ).withDescription( "use latest version" )
+                .create(USE_LATEST_VERSION_ARG);
+
+        options.addOption( useLatestVersion );
+
+        Option entityUUID =
+            OptionBuilder.withArgName(ENTITY_UUID).hasArg().isRequired( false ).withDescription( "specific entity uuid" )
+                .create(ENTITY_UUID);
+
+        options.addOption( entityUUID );
+
+
+
+        return options;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.apache.usergrid.tools.ToolBase#runTool(org.apache.commons.cli.CommandLine)
+     */
+    @Override
+    public void runTool( CommandLine line ) throws Exception {
+
+        logger.info("Starting Tool: EntityVersionAudit");
+        logger.info("Using Cassandra consistency level: {}", System.getProperty("usergrid.read.cl", "CL_LOCAL_QUORUM"));
+
+        startSpring();
+
+        String applicationOption = line.getOptionValue(APPLICATION_ARG);
+        String entityTypeOption = line.getOptionValue(ENTITY_TYPE_ARG);
+
+        if (isBlank(applicationOption)) {
+            throw new RuntimeException("Application ID not provided.");
+        }
+        final UUID app = UUID.fromString(line.getOptionValue(APPLICATION_ARG));
+
+        if (isBlank(entityTypeOption)) {
+            throw new RuntimeException("Entity type (singular collection name) not provided.");
+        }
+        String entityType = entityTypeOption;
+
+
+        boolean useLatestVersion =
+            line.getOptionValue(USE_LATEST_VERSION_ARG) != null && line.getOptionValue(USE_LATEST_VERSION_ARG).equalsIgnoreCase("true");
+        logger.info("useLatestVersion {}", useLatestVersion);
+
+        final String entityUUID = line.getOptionValue(ENTITY_UUID);
+        logger.info("entityUUID {}", entityUUID);
+
+
+        em = emf.getEntityManager( app );
+
+        String collectionName = InflectionUtils.pluralize(entityType);
+        String simpleEdgeType = CpNamingUtils.getEdgeTypeFromCollectionName(collectionName);
+        logger.info("simpleEdgeType: {}", simpleEdgeType);
+
+        ApplicationScope applicationScope = new ApplicationScopeImpl(new SimpleId(app, "application"));
+        Id applicationScopeId = applicationScope.getApplication();
+        logger.info("applicationScope.getApplication(): {}", applicationScopeId);
+
+        GraphManagerFactory gmf = injector.getInstance( GraphManagerFactory.class );
+        GraphManager gm = gmf.createEdgeManager(applicationScope);
+
+        EntityCollectionManagerFactory emf = injector.getInstance( EntityCollectionManagerFactory.class );
+        EntityCollectionManager ecm = emf.createCollectionManager(applicationScope);
+
+        final SimpleSearchByEdgeType search =
+            new SimpleSearchByEdgeType( applicationScopeId, simpleEdgeType, Long.MAX_VALUE, SearchByEdgeType.Order.DESCENDING,
+                Optional.absent(), false );
+
+        final IndexLocationStrategyFactory ilsf = injector.getInstance(IndexLocationStrategyFactory.class);
+        final Writer versionAuditWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("entity_version_audit.txt"), "utf-8"));
+        final Writer versionAggWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("entity_version_agg.txt"), "utf-8"));
+
+        versionAuditWriter.write("collection,entityUUID,entityVersion,cassandraTimestamp,elasticsearchTimestamp,indexDelayMillis,existsInElasticsearch\n");
+        versionAuditWriter.flush();
+
+        final EsProvider esProvider = injector.getInstance(EsProvider.class);
+
+        gm.loadEdgesFromSource(search).map(markedEdge -> {
+
+            UUID uuid = markedEdge.getTargetNode().getUuid();
+
+            if (entityUUID == null || uuid.equals(UUID.fromString(entityUUID))){
+                logger.info("matched uuid: {}", uuid);
+                try {
+                    EntityRef entityRef = new SimpleEntityRef(entityType, uuid);
+                    org.apache.usergrid.persistence.Entity retrieved = em.get(entityRef);
+
+                    if ( retrieved != null ){
+
+                        final AtomicInteger versionCount = new AtomicInteger();
+                        Observable<MvccLogEntry> versionObs = ecm.getVersionsFromMaxToMin( retrieved.asId(), org.apache.usergrid.utils.UUIDUtils.newTimeUUID() );
+                        if (useLatestVersion) {
+                            versionObs = versionObs.take(1);
+                        }
+                        versionObs.forEach( mvccLogEntry -> {
+
+                            IndexLocationStrategy strategy = ilsf.getIndexLocationStrategy(applicationScope);
+                            final String readAlias = strategy.getAlias().getReadAlias();
+
+                            final SearchEdge searchEdge = createSearchEdgeFromSource( new SimpleEdge( applicationScope.getApplication(),
+                                CpNamingUtils.getEdgeTypeFromCollectionName( InflectionUtils.pluralize( retrieved.asId().getType() ) ), retrieved.asId(),
+                                Long.MAX_VALUE ) );
+
+                            final String esDocId = createIndexDocId( applicationScope, retrieved.asId(), mvccLogEntry.getVersion(), searchEdge);
+                            GetResponse response =  esProvider.getClient().prepareGet(readAlias, "entity", esDocId)
+                                .execute()
+                                .actionGet();
+                            boolean exists = response.isExists();
+
+                            long indexTimestamp = response.getField("_timestamp") == null ? 0 : (long)response.getField("_timestamp").getValue();
+                            long uuidTimestamp = UUIDUtils.getTimestampInMillis(retrieved.getUuid());
+
+                            long diff = 0;
+                            if (indexTimestamp > 0) {
+                                diff = uuidTimestamp = indexTimestamp;
+                            }
+
+                            try {
+
+                                String csvLine =
+                                    collectionName + "," +
+                                    uuid + "," +
+                                    mvccLogEntry.getVersion() + "," +
+                                    uuidTimestamp + "," +
+                                    indexTimestamp + "," +
+                                    diff + "," +
+                                    exists;
+
+                                //final String url = "/"+readAlias+"/entity/"+URLEncoder.encode(esDocId, "UTF-8");
+                                versionAuditWriter.write(csvLine+"\n");
+                                versionAuditWriter.flush();
+                                versionCount.incrementAndGet();
+
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        });
+
+                        versionAggWriter.write(versionCount.toString()+","+retrieved.asId().getUuid()+"\n");
+                        versionAggWriter.flush();
+
+                    }else{
+                        logger.info("entity: {} NOT FOUND", uuid);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+
+           return markedEdge;
+        }).toBlocking().lastOrDefault(null);
+
+        versionAuditWriter.close();
+        versionAggWriter.close();
+
+    }
+}
diff --git a/website/content/index.html b/website/content/index.html
index 7dbabff..a80b1c2 100644
--- a/website/content/index.html
+++ b/website/content/index.html
@@ -14,8 +14,8 @@
             </div>
 
             <div class="btn-wrapper">
-                <iframe class="social-btn" src="/static/github-btn.html?user=apache&repo=usergrid&type=watch&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
-                <iframe class="social-btn" src="/static/github-btn.html?user=apache&repo=usergrid&type=fork&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
+                <iframe class="social-btn" src="https://ghbtns.com/github-btn.html?user=apache&repo=usergrid&type=watch&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
+                <iframe class="social-btn" src="https://ghbtns.com/github-btn.html?user=apache&repo=usergrid&type=fork&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="85" height="30"></iframe>
                 <!--<p><span class="or">or</span> <a href="#">Download Usergrid</a></p>-->
             </div>
 
diff --git a/website/content/static/github-btn.html b/website/content/static/github-btn.html
deleted file mode 100644
index 76a7c55..0000000
--- a/website/content/static/github-btn.html
+++ /dev/null
@@ -1,2 +0,0 @@
-
-<html><body><style type="text/css">body{padding:0;margin:0;font:bold 11px/14px "Helvetica Neue",Helvetica,Arial,sans-serif;text-rendering:optimizeLegibility;overflow:hidden}.github-btn{height:20px;overflow:hidden}.gh-btn,.gh-count,.gh-ico{float:left}.gh-btn,.gh-count{padding:2px 5px 2px 4px;color:#555;text-decoration:none;text-shadow:0 1px 0 #fff;white-space:nowrap;cursor:pointer;border-radius:3px}.gh-btn{background-color:#e6e6e6;background-image:-webkit-gradient(linear,0 0,0 100%,from(#fafafa),to(#eaeaea));background-image:-webkit-linear-gradient(#fafafa,#eaeaea);background-image:-moz-linear-gradient(top,#fafafa,#eaeaea);background-image:-ms-linear-gradient(#fafafa,#eaeaea);background-image:-o-linear-gradient(#fafafa,#eaeaea);background-image:linear-gradient(#fafafa,#eaeaea);background-repeat:no-repeat;border:1px solid #d4d4d4;border-bottom-color:#bcbcbc}.gh-btn:hover,.gh-btn:focus,.gh-btn:active{color:#fff;text-decoration:none;text-shadow:0 -1px 0 rgba(0,0,0,.25);border-color:#518cc6 #518cc6 #2a65a0;background-color:#3072b3}.gh-btn:hover,.gh-btn:focus{background-image:-webkit-gradient(linear,0 0,0 100%,from(#599bdc),to(#3072b3));background-image:-webkit-linear-gradient(#599bdc,#3072b3);background-image:-moz-linear-gradient(top,#599bdc,#3072b3);background-image:-ms-linear-gradient(#599bdc,#3072b3);background-image:-o-linear-gradient(#599bdc,#3072b3);background-image:linear-gradient(#599bdc,#3072b3)}.gh-btn:active{background-image:none;-webkit-box-shadow:inset 0 2px 5px rgba(0,0,0,.10);-moz-box-shadow:inset 0 2px 5px rgba(0,0,0,.10);box-shadow:inset 0 2px 5px rgba(0,0,0,.10)}.gh-ico{width:14px;height:15px;margin-top:-1px;margin-right:4px;vertical-align:middle;background-image:url(data:image/png;base64,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);background-repeat:no-repeat;background-position:0 0}.gh-btn:hover .gh-ico,.gh-btn:focus .gh-ico,.gh-btn:active .gh-ico{background-position:-25px 0}.gh-count{position:relative;display:none;margin-left:4px;background-color:#fafafa;border:1px solid #d4d4d4}.gh-count:hover,.gh-count:focus{color:#4183c4}.gh-count:before,.gh-count:after{content:' ';position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid}.gh-count:before{top:50%;left:-3px;margin-top:-4px;border-width:4px 4px 4px 0;border-right-color:#fafafa}.gh-count:after{top:50%;left:-4px;z-index:-1;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#d4d4d4}.github-btn-large{height:30px}.github-btn-large .gh-btn,.github-btn-large .gh-count{padding:3px 10px 3px 8px;font-size:16px;line-height:22px;border-radius:4px}.github-btn-large .gh-ico{width:22px;height:23px;background-position:0 -20px}.github-btn-large .gh-btn:hover .gh-ico,.github-btn-large .gh-btn:focus .gh-ico,.github-btn-large .gh-btn:active .gh-ico{background-position:-25px -20px}.github-btn-large .gh-count{margin-left:6px}.github-btn-large .gh-count:before{left:-5px;margin-top:-6px;border-width:6px 6px 6px 0}.github-btn-large .gh-count:after{left:-6px;margin-top:-7px;border-width:7px 7px 7px 0}@media(-moz-min-device-pixel-ratio:2),(-o-min-device-pixel-ratio:2/1),(-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2){.gh-ico{background-image:url(data:image/png;base64,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);background-size:50px 45px}}</style> <span class=github-btn id=github-btn> <a class=gh-btn id=gh-btn href="#" target=_blank> <span class=gh-ico></span> <span class=gh-text id=gh-text></span> </a> <a class=gh-count id=gh-count href="#" target=_blank></a> </span> <script type="text/javascript">var params=function(){var d=[],c;var a=window.location.href.slice(window.location.href.indexOf("?")+1).split("&");for(var b=0;b<a.length;b++){c=a[b].split("=");d.push(c[0]);d[c[0]]=c[1]}return d}();var user=params.user,repo=params.repo,type=params.type,count=params.count,size=params.size,head=document.getElementsByTagName("head")[0],button=document.getElementById("gh-btn"),mainButton=document.getElementById("github-btn"),text=document.getElementById("gh-text"),counter=document.getElementById("gh-count");function addCommas(a){return String(a).replace(/(\d)(?=(\d{3})+$)/g,"$1,")}function jsonp(b){var a=document.createElement("script");a.src=b+"?callback=callback";head.insertBefore(a,head.firstChild)}function callback(a){if(type=="watch"){counter.innerHTML=addCommas(a.data.watchers)}else{if(type=="fork"){counter.innerHTML=addCommas(a.data.forks)}else{if(type=="follow"){counter.innerHTML=addCommas(a.data.followers)}}}if(count=="true"){counter.style.display="block"}}button.href="https://github.com/"+user+"/"+repo+"/";if(type=="watch"){mainButton.className+=" github-watchers";text.innerHTML="Star";counter.href="https://github.com/"+user+"/"+repo+"/stargazers"}else{if(type=="fork"){mainButton.className+=" github-forks";text.innerHTML="Fork";counter.href="https://github.com/"+user+"/"+repo+"/network"}else{if(type=="follow"){mainButton.className+=" github-me";text.innerHTML="Follow @"+user;button.href="https://github.com/"+user;counter.href="https://github.com/"+user+"/followers"}}}if(size=="large"){mainButton.className+=" github-btn-large"}if(type=="follow"){jsonp("https://api.github.com/users/"+user)}else{jsonp("https://api.github.com/repos/"+user+"/"+repo)};</script></body></html>
\ No newline at end of file
diff --git a/website/tmp/checksums b/website/tmp/checksums
deleted file mode 100644
index f586065..0000000
--- a/website/tmp/checksums
+++ /dev/null
Binary files differ
diff --git a/website/tmp/compiled_content b/website/tmp/compiled_content
deleted file mode 100644
index 91c5445..0000000
--- a/website/tmp/compiled_content
+++ /dev/null
Binary files differ
diff --git a/website/tmp/dependencies b/website/tmp/dependencies
deleted file mode 100644
index 8ddff40..0000000
--- a/website/tmp/dependencies
+++ /dev/null
Binary files differ