You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2015/08/10 19:32:32 UTC

[01/50] [abbrv] allura git commit: [#7897] ticket:824 Fix text wrapping and list styles in preview/edit mode for replies

Repository: allura
Updated Branches:
  refs/heads/hs/7925 7d57e2db8 -> 4090d3be8 (forced update)


[#7897] ticket:824 Fix text wrapping and list styles in preview/edit mode for replies


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d3a99a4e
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d3a99a4e
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d3a99a4e

Branch: refs/heads/hs/7925
Commit: d3a99a4e8f79691f653f30386a5390ee951a11f4
Parents: c9b39c9
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 22 11:41:45 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d3a99a4e/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 80081e4..a188133 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -2636,10 +2636,18 @@ div.attachment_thumb .file_type span {
   width: 74%;
 }
 
+#comment .edit_post_form ul,
+#comment .reply_post_form ul,
 #comment .display_post ul {
   float: none;
   padding-left: 1em;
   list-style-type: disc;
+  margin-bottom: 20px !important;
+}
+#comment .edit_post_form ul,
+#comment .reply_post_form ul {
+  padding-left: 1.5em;
+  width: 95%
 }
 
 .reply {


[32/50] [abbrv] allura git commit: [#7925] Update tests to work with new diff processing

Posted by he...@apache.org.
[#7925] Update tests to work with new diff processing


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/04b87c66
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/04b87c66
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/04b87c66

Branch: refs/heads/hs/7925
Commit: 04b87c6612c2c1ae4b1dd933e7a7f3734d251228
Parents: 7f738bd
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Mon Jul 27 16:08:05 2015 -0400
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:35 2015 -0400

----------------------------------------------------------------------
 Allura/allura/tests/model/test_repo.py          |  2 +
 .../forgegit/tests/model/test_repository.py     | 10 ++++
 .../forgesvn/tests/model/test_repository.py     | 59 +++++++++++++-------
 3 files changed, 52 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/04b87c66/Allura/allura/tests/model/test_repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py
index 1f6ec3c..c0a6bc8 100644
--- a/Allura/allura/tests/model/test_repo.py
+++ b/Allura/allura/tests/model/test_repo.py
@@ -143,6 +143,8 @@ class TestLastCommit(unittest.TestCase):
         self.repo.paged_diffs.return_value = {
             'added': [],
             'removed': [],
+            'copied': [],
+            'renamed': [],
             'changed': [],
             'total': 0,
         }

http://git-wip-us.apache.org/repos/asf/allura/blob/04b87c66/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 9f007e6..948f228 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -670,6 +670,8 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
             'added': [u'with space.txt', u'привіт.txt'],
             'removed': [],
             'changed': [],
+            'copied': [],
+            'renamed': [],
             'total': 2,
         }
         assert_equals(diffs, expected)
@@ -678,6 +680,8 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
         expected = {
             'added': [],
             'removed': [],
+            'copied': [],
+            'renamed': [],
             'changed': [u'привіт.txt'],
             'total': 1,
         }
@@ -689,6 +693,8 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
             'added': [u'README.md'],
             'removed': [],
             'changed': [],
+            'copied': [],
+            'renamed': [],
             'total': 1,
         }
         assert_equals(diffs, expected)
@@ -698,6 +704,8 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
         expected = {
             'added': [u'with space.txt'],
             'removed': [],
+            'copied': [],
+            'renamed': [],
             'changed': [],
             'total': 2,
         }
@@ -706,6 +714,8 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
         expected = {
             'added': [u'привіт.txt'],
             'removed': [],
+            'copied': [],
+            'renamed': [],
             'changed': [],
             'total': 2,
         }

http://git-wip-us.apache.org/repos/asf/allura/blob/04b87c66/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 79beb52..9889a60 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -363,7 +363,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         self.assertEqual(entry.diffs, entry.paged_diffs(start=0))
         added_expected = entry.diffs.added[1:3]
         expected = dict(
-            copied=[], changed=[], removed=[],
+            copied=[], changed=[], removed=[], renamed=[],
             added=added_expected, total=4)
         actual = entry.paged_diffs(start=1, end=3)
         self.assertEqual(expected, actual)
@@ -376,7 +376,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         entry = self.repo.commit(self.repo.log(1, id_only=True).next())
         self.assertEqual(
             entry.diffs, dict(
-                copied=[], changed=[],
+                copied=[], changed=[], renamed=[],
                 removed=[], added=['/README'], total=1))
 
     def test_diff_create_path(self):
@@ -385,7 +385,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         actual.added = sorted(actual.added)
         self.assertEqual(
             entry.diffs, dict(
-                copied=[], changed=[], removed=[],
+                copied=[], changed=[], removed=[], renamed=[],
                 added=sorted([
                     '/a', '/a/b', '/a/b/c',
                     '/a/b/c/hello.txt']), total=4))
@@ -394,20 +394,20 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         entry = self.repo.commit(self.repo.log(3, id_only=True).next())
         self.assertEqual(
             entry.diffs, dict(
-                copied=[], changed=['/README'],
+                copied=[], changed=['/README'], renamed=[],
                 removed=[], added=[], total=1))
 
     def test_diff_delete(self):
         entry = self.repo.commit(self.repo.log(4, id_only=True).next())
         self.assertEqual(
             entry.diffs, dict(
-                copied=[], changed=[],
+                copied=[], changed=[], renamed=[],
                 removed=['/a/b/c/hello.txt'], added=[], total=1))
 
     def test_diff_copy(self):
         entry = self.repo.commit(self.repo.log(5, id_only=True).next())
         assert_equals(dict(entry.diffs), dict(
-                copied=[{'new': u'/b', 'old': u'/a', 'diff': '', 'ratio': 1}],
+                copied=[{'new': u'/b', 'old': u'/a', 'diff': '', 'ratio': 1}],  renamed=[],
                 changed=[], removed=[], added=[], total=1))
 
     def test_commit(self):
@@ -1002,6 +1002,8 @@ class TestCommit(_TestWithRepo):
         self.repo._impl.paged_diffs.return_value = {
             'added': ['a', 'a/a', 'a/a/a', 'a/a/b', 'a/b'],
             'changed': [],
+            'copied': [],
+            'renamed': [],
             'removed': [],
             'total': 5,
         }
@@ -1024,6 +1026,8 @@ class TestCommit(_TestWithRepo):
         self._make_log(ci)
         self.repo._impl.paged_diffs.return_value = {
             'added': ['b', 'b/a', 'b/a/a', 'b/a/b', 'b/b'],
+            'renamed': [],
+            'copied': [],
             'changed': [],
             'removed': ['a', 'a/a', 'a/a/a', 'a/a/b', 'a/b'],
             'total': 10,
@@ -1044,25 +1048,38 @@ class TestCommit(_TestWithRepo):
         ci.parent_ids = ['bar']
         self._make_log(ci)
         self.repo._impl.paged_diffs.return_value = {
-            'added': ['b/c', 'b/a/z'],
+            'added': [u'b/c', u'b/a/z'],
+            'removed': [u'/b/a/b', u'b/b'],
             'changed': [],
-            'removed': ['b/a/b', 'b/b', 'b/a/a'],
-            'total': 10,
+            'copied': [
+                {
+                    'new': u'b/c',
+                    'old': u'b/a/b',
+                    'ratio': 1,
+                    'diff': '',
+                },
+                {
+                    'new': u'b/a/z',
+                    'old': u'b/b',
+                    'ratio': 1,
+                    'diff': '',
+                },
+            ],
+            'renamed': [],
+            'total': 2
         }
         M.repo_refresh.refresh_commit_trees(ci, {})
-        assert_equal(ci.diffs.added, [])
+        assert_equal(ci.diffs.added, [u'b/a/z', u'b/c'])
         assert_equal(ci.diffs.changed, [])
-        assert_equal(ci.diffs.removed, ['b/a/a'])
+        assert_equal(ci.diffs.removed, [u'/b/a/b', u'b/b'])
         # see mock for open_blob
         assert_equal(len(ci.diffs.copied), 2)
-        assert_equal(ci.diffs.copied[0]['old'], 'b/a/b')
-        assert_equal(ci.diffs.copied[0]['new'], 'b/c')
-        assert_equal(ci.diffs.copied[0]['ratio'], 1)
-        assert_equal(ci.diffs.copied[0]['diff'], '')
-        assert_equal(ci.diffs.copied[1]['old'], 'b/b')
-        assert_equal(ci.diffs.copied[1]['new'], 'b/a/z')
-        assert ci.diffs.copied[1]['ratio'] < 1, ci.diffs.copied[1]['ratio']
-        assert '+++' in ci.diffs.copied[1]['diff'], ci.diffs.copied[1]['diff']
+        assert_equal(ci.diffs.copied[1]['old'], 'b/a/b')
+        assert_equal(ci.diffs.copied[1]['new'], 'b/c')
+        assert_equal(ci.diffs.copied[1]['ratio'], 1)
+        assert_equal(ci.diffs.copied[1]['diff'], '')
+        assert_equal(ci.diffs.copied[0]['old'], 'b/b')
+        assert_equal(ci.diffs.copied[0]['new'], 'b/a/z')
 
     def test_context(self):
         self.ci.context()
@@ -1132,6 +1149,7 @@ class TestDirectRepoAccess(object):
             'removed': [],
             'changed': [],
             'copied': [],
+            'renamed': [],
             'total': 1,
         }
         assert_equals(diffs, expected)
@@ -1142,6 +1160,7 @@ class TestDirectRepoAccess(object):
             'added': [u'/a', u'/a/b', u'/a/b/c', u'/a/b/c/hello.txt'],
             'removed': [],
             'changed': [],
+            'renamed': [],
             'copied': [],
             'total': 4,
         }
@@ -1152,6 +1171,7 @@ class TestDirectRepoAccess(object):
         expected = {
             'added': [],
             'removed': [],
+            'renamed': [],
             'changed': [u'/README'],
             'copied': [],
             'total': 1,
@@ -1164,6 +1184,7 @@ class TestDirectRepoAccess(object):
             'added': [],
             'removed': ['/a/b/c/hello.txt'],
             'changed': [],
+            'renamed': [],
             'copied': [],
             'total': 1,
         }


[44/50] [abbrv] allura git commit: [#7925] include renames in webhook payload

Posted by he...@apache.org.
[#7925] include renames in webhook payload


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/95f56486
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/95f56486
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/95f56486

Branch: refs/heads/hs/7925
Commit: 95f56486ae75a01864d50ada7b6c49a166025e63
Parents: 7133cb1
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 20:49:01 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:37 2015 -0400

----------------------------------------------------------------------
 Allura/allura/model/repository.py                | 1 +
 ForgeGit/forgegit/tests/model/test_repository.py | 8 +++++---
 ForgeSVN/forgesvn/tests/model/test_repository.py | 6 ++++--
 3 files changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/95f56486/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 3db43a8..acbc3d1 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -1275,6 +1275,7 @@ class Commit(RepoObject, ActivityObject):
             'removed': self.diffs.removed,
             'modified': self.diffs.changed,
             'copied': self.diffs.copied,
+            'renamed': self.diffs.renamed,
         }
 
 

http://git-wip-us.apache.org/repos/asf/allura/blob/95f56486/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 948f228..25daa62 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -121,7 +121,7 @@ class TestNewGit(unittest.TestCase):
         assert_equal(
             sorted(rev.webhook_info.keys()),
             sorted(['id', 'url', 'timestamp', 'message', 'author',
-                    'committer', 'added', 'removed', 'modified', 'copied']))
+                    'committer', 'added', 'removed', 'renamed', 'modified', 'copied']))
 
 
 class TestGitRepo(unittest.TestCase, RepoImplTestBase):
@@ -568,7 +568,8 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
                 'added': [u'bad'],
                 'removed': [],
                 'modified': [],
-                'copied': []
+                'copied': [],
+                'renamed': [],
             }, {
                 'id': u'1e146e67985dcd71c74de79613719bef7bddca4a',
                 'url': u'http://localhost/p/test/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/',
@@ -583,7 +584,8 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
                 'added': [],
                 'removed': [],
                 'modified': [u'README'],
-                'copied': []
+                'copied': [],
+                'renamed': [],
             }],
             'repository': {
                 'name': u'Git',

http://git-wip-us.apache.org/repos/asf/allura/blob/95f56486/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 9889a60..1c997b7 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -102,7 +102,7 @@ class TestNewRepo(unittest.TestCase):
         assert_equal(
             sorted(self.rev.webhook_info.keys()),
             sorted(['id', 'url', 'timestamp', 'message', 'author',
-                    'committer', 'added', 'removed', 'modified', 'copied']))
+                    'committer', 'added', 'removed', 'renamed', 'modified', 'copied']))
 
 
 class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
@@ -595,7 +595,8 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
                 'added': [u'/ЗРЯЧИЙ_ТА_ПОБАЧИТЬ'],
                 'removed': [],
                 'modified': [],
-                'copied': []
+                'copied': [],
+                'renamed': [],
             }, {
                 'id': u'r5',
                 'url': u'http://localhost/p/test/src/5/',
@@ -613,6 +614,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
                 'copied': [
                     {'new': u'/b', 'old': u'/a', 'diff': '', 'ratio': 1},
                 ],
+                'renamed': [],
             }],
             'repository': {
                 'name': u'SVN',


[37/50] [abbrv] allura git commit: [#7925] remove --find-copies-harder due to false-positives

Posted by he...@apache.org.
[#7925] remove --find-copies-harder due to false-positives


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/155e0b0f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/155e0b0f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/155e0b0f

Branch: refs/heads/hs/7925
Commit: 155e0b0fcdecedee1df4bb3fdcf394952c6f580d
Parents: 73385a8
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 16:09:59 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:36 2015 -0400

----------------------------------------------------------------------
 ForgeGit/forgegit/model/git_repo.py | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/155e0b0f/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 9a8549a..ece0d6c 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -651,7 +651,6 @@ class GitImplementation(M.RepositoryImplementation):
             '--name-status',
             '--no-abbrev',
             '--root',
-            '--find-copies-harder',
             # show tree entry itself as well as subtrees (Commit.added_paths relies on this)
             '-t',
             '-z',  # don't escape filenames and use \x00 as fields delimiter


[22/50] [abbrv] allura git commit: [#7930] ticket:829 Don't update project's last_updated on thread view

Posted by he...@apache.org.
[#7930] ticket:829 Don't update project's last_updated on thread view


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/26d0e066
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/26d0e066
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/26d0e066

Branch: refs/heads/hs/7925
Commit: 26d0e066e2e886ad5d4c4df7d9fb2f4e139208ce
Parents: 0015f47
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Aug 3 17:24:53 2015 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 5 19:00:35 2015 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py                   |  2 ++
 .../forgediscussion/tests/functional/test_forum.py     | 13 +++++++++++++
 2 files changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/26d0e066/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index b329b01..df8076d 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -110,6 +110,7 @@ class DiscussionController(BaseController, FeedController):
             else:
                 thread['subscription'] = False
             M.session.artifact_orm_session._get().skip_mod_date = True
+            M.session.artifact_orm_session._get().skip_last_updated = True
         redirect(request.referer)
 
     def get_feed(self, project, app, user):
@@ -193,6 +194,7 @@ class ThreadController(BaseController, FeedController):
         self.thread.num_views += 1
         # the update to num_views shouldn't affect it
         M.session.artifact_orm_session._get().skip_mod_date = True
+        M.session.artifact_orm_session._get().skip_last_updated = True
         count = self.thread.query_posts(page=page, limit=int(limit)).count()
         return dict(discussion=self.thread.discussion,
                     thread=self.thread,

http://git-wip-us.apache.org/repos/asf/allura/blob/26d0e066/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index ae91bf0..23ec71f 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -831,6 +831,19 @@ class TestForum(TestController):
         r = self.app.get(u'/p/test/discussion/create_topic/téstforum/'.encode('utf-8'))
         assert u'<option value="téstforum" selected>Tést Forum</option>' in r
 
+    def test_viewing_a_thread_does_not_update_project_last_updated(self):
+        # Create new topic/thread
+        r = self.app.get('/discussion/create_topic/')
+        url = self.fill_new_topic_form(r).submit().follow().request.url
+
+        # Remember project's last_updated
+        timestamp_before = M.Project.query.get(shortname='test').last_updated
+
+        # View the thread and make sure project last_updated is not updated
+        thread = self.app.get(url)
+        timestamp_after = M.Project.query.get(shortname='test').last_updated
+        assert_equal(timestamp_before, timestamp_after)
+
 
 class TestForumStats(TestController):
     def test_stats(self):


[23/50] [abbrv] allura git commit: [#7915] ticket:831 Move installation instructions into the docs

Posted by he...@apache.org.
[#7915] ticket:831 Move installation instructions into the docs


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/a8ace0d5
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/a8ace0d5
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/a8ace0d5

Branch: refs/heads/hs/7925
Commit: a8ace0d5e30c52d4a90fdcdb1f235b4f7861b1af
Parents: 26d0e06
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Aug 3 21:08:06 2015 +0300
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Aug 5 17:53:22 2015 -0400

----------------------------------------------------------------------
 Allura/docs/development/contributing.rst     |   4 +-
 Allura/docs/getting_started/installation.rst | 340 +++++++++++++++++++++-
 INSTALL-docker.markdown                      | 117 --------
 INSTALL.markdown                             | 154 +---------
 NOTICE                                       |   2 +-
 README.markdown                              |   2 +-
 6 files changed, 342 insertions(+), 277 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a8ace0d5/Allura/docs/development/contributing.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/development/contributing.rst b/Allura/docs/development/contributing.rst
index 3e6c8d9..2dff6ad 100644
--- a/Allura/docs/development/contributing.rst
+++ b/Allura/docs/development/contributing.rst
@@ -39,8 +39,8 @@ so you can see and test the changes you make. You can install Allura from
 scratch, or by using our pre-built Vagrant image. Instructions for these
 approaches can be found here:
 
-* `Install from scratch <https://forge-allura.apache.org/p/allura/git/ci/master/tree/INSTALL.markdown>`_
-* `Install from Vagrant image <https://forge-allura.apache.org/p/allura/wiki/Install%20and%20Run%20Allura%20-%20Vagrant/>`_
+* :ref:`Install from scratch <step-by-step-install>`
+* :ref:`Install using Docker <docker-install>`
 
 Managing Services
 -----------------

http://git-wip-us.apache.org/repos/asf/allura/blob/a8ace0d5/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index 30425b4..90fbeee 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -19,12 +19,346 @@
 Installation
 ************
 
+.. contents::
+   :local:
 
-Our step-by-step setup instructions are in our INSTALL.markdown file.  You can read it online at https://forge-allura.apache.org/p/allura/git/ci/master/tree/INSTALL.markdown  You should be able to get Allura up and running in well under an hour by following those instructions.
+.. _step-by-step-install:
 
-For a faster and easier setup, see our `Vagrant/VirtualBox installation guide <https://forge-allura.apache.org/p/allura/wiki/Install%20and%20Run%20Allura%20-%20Vagrant/>`_
+Step-by-Step Installation
+-------------------------
+
+For a simpler setup using Docker images, see :ref:`docker-install` instead.
+
+In these instructions, we'll use `VirtualBox <http://www.virtualbox.org>`_ and `Ubuntu 14.04 <http://ubuntu.com>`_ (12.04 works too) to create a disposable sandbox for Allura development/testing.  Allura should work on other Linux systems (including OSX), but setting up all the dependencies will be different.
+
+* Download and install `VirtualBox <http://www.virtualbox.org/wiki/Downloads>`_ for your platform.
+
+* Download a minimal `Ubuntu 14.04 64-bit ISO <https://help.ubuntu.com/community/Installation/MinimalCD>`_.
+
+* Create a new virtual machine in Virtual Box, selecting Ubuntu (64 bit) as the OS type.  The rest of the wizards' defaults are fine.
+
+* When you launch the virtual machine for the first time, you will be prompted to attach your installation media.  Browse to the :file:`mini.iso` that you downloaded earlier.
+
+* After a text-only installation, you may end up with a blank screen and blinking cursor.  Press :code:`Alt-F1` to switch to the first console.
+
+* Consult `available documentation <https://help.ubuntu.com/>`_ for help installing Ubuntu.
+
+
+Installation
+^^^^^^^^^^^^
+
+Before we begin, you'll need to install some system packages.
+
+.. code-block:: bash
+
+    ~$ sudo aptitude install git-core default-jre-headless python-dev libssl-dev libldap2-dev libsasl2-dev libjpeg8-dev zlib1g-dev
+
+To install MongoDB, follow the instructions `here <http://docs.mongodb.org/v2.6/tutorial/install-mongodb-on-ubuntu/>`_.
+
+Optional, for SVN support:
+
+.. code-block:: bash
+
+    ~$ sudo aptitude install subversion python-svn
+
+Setting up a virtual python environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The first step to installing the Allura platform is installing a virtual environment via `virtualenv <https://virtualenv.pypa.io/en/latest/>`_.  This helps keep our distribution python installation clean.
+
+.. code-block:: bash
+
+    ~$ sudo aptitude install python-pip
+    ~$ sudo pip install virtualenv
+
+Once you have virtualenv installed, you need to create a virtual environment.  We'll call our Allura environment 'env-allura'.
+
+.. code-block:: bash
+
+    ~$ virtualenv env-allura
+
+This gives us a nice, clean environment into which we can install all the allura dependencies.
+In order to use the virtual environment, you'll need to activate it:
+
+.. code-block:: bash
+
+    ~$ . env-allura/bin/activate
+
+You'll need to do this whenever you're working on the Allura codebase so you may want to consider adding it to your :file:`~/.bashrc` file.
+
+Creating the log directory
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+    (env-allura)~$ sudo mkdir -p /var/log/allura
+    (env-allura)~$ sudo chown $(whoami) /var/log/allura
+
+Installing the Allura code and dependencies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now we can get down to actually getting the Allura code and dependencies downloaded and ready to go.  If you don't have the source code yet, run:
+
+.. code-block:: bash
+
+    (env-allura)~$ mkdir src
+    (env-allura)~$ cd src
+    (env-allura)~/src$ git clone https://git-wip-us.apache.org/repos/asf/allura.git allura
+
+If you already reading this file from an Allura release or checkout, you're ready to continue.
+
+Although the application :file:`setup.py` files define a number of dependencies, the :file:`requirements.txt` files are currently the authoritative source, so we'll use those with `pip <https://pip.pypa.io/en/stable/>`_ to make sure the correct versions are installed.
+
+.. code-block:: bash
+
+    (env-allura)~/src$ cd allura
+    (env-allura)~/src/allura$ pip install -r requirements.txt
+
+This will take a while.  If you get an error from pip, it is typically a temporary download error.  Just run the command again and it will quickly pass through the packages it already downloaded and then continue.
+
+Optional, for SVN support: symlink the system pysvn package into our virtual environment
+
+.. code-block:: bash
+
+    (env-allura)~/src/allura$ ln -s /usr/lib/python2.7/dist-packages/pysvn ~/env-allura/lib/python2.7/site-packages/
+
+Next, run :code:`./rebuild-all.bash` to setup all the Allura applications.  If you only want to use a few tools, run:
+
+.. code-block:: bash
+
+    (env-allura)~/src/allura$ cd Allura
+    (env-allura)~/src/allura/Allura$ python setup.py develop
+    (env-allura)~/src/allura/Allura$ cd ../ForgeWiki   # required tool
+    (env-allura)~/src/allura/ForgeWiki$ python setup.py develop
+    # repeat for any other tools you want to use
+
+Initializing the environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Allura forge consists of several components, all of which need to be running to have full functionality.
+
+SOLR search and indexing server
+*******************************
+
+We have a custom config ready for use.
+
+.. code-block:: bash
+
+    (env-allura)~$ cd ~/src
+    (env-allura)~/src$ wget -nv http://archive.apache.org/dist/lucene/solr/4.2.1/solr-4.2.1.tgz
+    (env-allura)~/src$ tar xf solr-4.2.1.tgz && rm -f solr-4.2.1.tgz
+    (env-allura)~/src$ cp -f allura/solr_config/schema.xml solr-4.2.1/example/solr/collection1/conf
+
+    (env-allura)~/src$ cd solr-4.2.1/example/
+    (env-allura)~/src/apache-solr-4.2.1/example/$ nohup java -jar start.jar > /var/log/allura/solr.log &
+
+
+Create code repo directories
+****************************
+
+The default configuration stores repos in :file:`/srv`, so we need to create those directories:
+
+.. code-block:: bash
+
+    ~$ sudo mkdir /srv/{git,svn,hg}
+    ~$ sudo chown $USER /srv/{git,svn,hg}
+    ~$ sudo chmod 775 /srv/{git,svn,hg}
+
+If you don't have :code:`sudo` permission or just want to store them somewhere else, change the :file:`/srv` paths in :file:`development.ini`
+
+If you want to set up remote access to the repositories, see :ref:`scm_hosting`
+
+Allura task processing
+**********************
+
+Allura uses a background task service called "taskd" to do async tasks like sending emails, and indexing data into solr, etc.  Let's get it running
+
+.. code-block:: bash
+
+    (env-allura)~$ cd ~/src/allura/Allura
+    (env-allura)~/src/allura/Allura$ nohup paster taskd development.ini > /var/log/allura/taskd.log 2>&1 &
+
+The application server
+**********************
+
+In order to initialize the Allura database, you'll need to run the following:
+
+For development setup:
+
+.. code-block:: bash
+
+    (env-allura)~/src/allura/Allura$ paster setup-app development.ini
+
+For production setup:
+
+.. code-block:: bash
+
+    (env-allura)~/src/allura/Allura$ ALLURA_TEST_DATA=False paster setup-app development.ini
+
+This shouldn't take too long, but it will start the taskd server doing tons of stuff in the background.  Once this is done, you can start the application server:
+
+.. code-block:: bash
+
+    (env-allura)~/src/allura/Allura$ nohup paster serve --reload development.ini  > /var/log/allura/allura.log 2>&1 &
+
+Next Steps
+~~~~~~~~~~
+
+Go to the Allura webapp running on your `local machine <http://localhost:8080/>`_ port 8080.
+(If you're running this inside a VM, you'll probably have to configure the port forwarding settings)
+
+You can log in with username `admin1`, `test-user` or `root`.  They all have password "foo".  (For more details
+on the default data, see :file:`bootstrap.py`)
+
+There are a few default projects (like "test") and neighborhoods.  Feel free to experiment with them.  If you want to
+register a new project in your own forge, visit `/p/add_project`.
+
+Extra
+~~~~~
+
+* Read :ref:`post-setup-instructions`
+* Ask questions and discuss Allura on the `allura-dev mailing list <http://mail-archives.apache.org/mod_mbox/allura-dev/>`_
+* Run the test suite (slow): :code:`$ ALLURA_VALIDATION=none ./run_tests`
+* File bug reports at https://forge-allura.apache.org/p/allura/tickets/new/ (login required)
+* Contribute code according to `this guide <https://forge-allura.apache.org/p/allura/wiki/Contributing%20Code/>`_
+
+.. _docker-install:
+
+Using Docker
+------------
+
+General info
+^^^^^^^^^^^^
+
+Allura runs on the following docker containers:
+
+- web
+- mongo
+- taskd
+- solr
+- inmail
+- outmail
+
+Host-mounted volumes
+~~~~~~~~~~~~~~~~~~~~
+
+These are created on first run.
+
+Current directory mounted as :file:`/allura` inside containers.
+
+Python environment:
+
+- :file:`env-docker/python`
+- :file:`env-docker/bin`
+
+Services data:
+
+- :file:`/allura-data/mongo` - mongo data
+- :file:`/allura-data/solr` - SOLR index
+- :code:`/allura-data/scm/{git,hg,svn}` - code repositories
+- :file:`/allura-data/scm/snapshots` - generated code snapshots
+
+Ports, exposed to host system
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- 8080 - webapp
+- 8983 - SOLR admin panel (http://localhost:8983/solr/)
+- 8825 - incoming mail listener
+
+
+First run
+^^^^^^^^^
+
+`Download the latest release <http://www.apache.org/dyn/closer.cgi/allura/>`_ of Allura, or `clone from git <https://forge-allura.apache.org/p/allura/git/ci/master/tree/>`_ for the bleeding edge.
+
+Install `Docker <http://docs.docker.com/installation/>`_ and `Docker Compose <https://docs.docker.com/compose/install/>`_.
+
+Build/fetch all required images (run these in allura source directory):
+
+.. code-block:: bash
+
+    ~$ docker-compose build
+
+Install requirements:
+
+.. code-block:: bash
+
+    ~$ docker-compose run web pip install -r requirements.txt
+
+Install Allura packages:
+
+.. code-block:: bash
+
+    ~$ docker-compose run web ./rebuild-all.bash
+
+Initialize database with test data:
+
+.. code-block:: bash
+
+    ~$ docker-compose run web bash -c 'cd Allura && paster setup-app docker-dev.ini'
+
+If you want to skip test data creation you can instead run:
+
+.. code-block:: bash
+
+    ~$ docker-compose run web bash -c 'cd Allura && ALLURA_TEST_DATA=False paster setup-app docker-dev.ini'
+
+Start containers in the background:
+
+.. code-block:: bash
+
+    ~$ docker-compose up -d
+
+Useful commands
+^^^^^^^^^^^^^^^
+
+Restarting all containers:
+
+.. code-block:: bash
+
+    ~$ docker-compose up -d
+
+View logs from all services:
+
+.. code-block:: bash
+
+    ~$ docker-compose logs
+
+You can specify one or more services to view logs only from them, e.g. to see
+outgoing mail:
+
+.. code-block:: bash
+
+    ~$ docker-compose logs outmail
+
+Update requirements and reinstall apps:
+
+.. code-block:: bash
+
+    ~$ docker-compose run web pip install -r requirements.txt
+    ~$ docker-compose run web ./rebuild-all.bash
+
+You may want to restart at least "taskd" container after that in order for it to
+pick up changes.
+
+Running all tests:
+
+.. code-block:: bash
+
+    ~$ docker-compose run web ./run_tests
+
+Running subset of tests:
+
+.. code-block:: bash
+
+    ~$ docker-compose run web bash -c 'cd ForgeGit && nosetests forgegit.tests.functional.test_controllers:TestFork'
+
+Connecting to mongo directly:
+
+.. code-block:: bash
+
+    ~$ docker-compose run mongo mongo --host mongo
 
-That's all for the development setup.  For the production setup see :ref:`next section <post-setup-instructions>`.
 
 .. _post-setup-instructions:
 

http://git-wip-us.apache.org/repos/asf/allura/blob/a8ace0d5/INSTALL-docker.markdown
----------------------------------------------------------------------
diff --git a/INSTALL-docker.markdown b/INSTALL-docker.markdown
deleted file mode 100644
index c4fb810..0000000
--- a/INSTALL-docker.markdown
+++ /dev/null
@@ -1,117 +0,0 @@
-<!--
-    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.
--->
-
-# General info
-
-## Allura runs on following docker containers:
-
-- web
-- mongo
-- taskd
-- solr
-- inmail
-- outmail
-
-## Host-mounted volumes (created on first run)
-
-Current directory mounted as `/allura` inside containers.
-
-Python environment:
-
-- `env-docker/python`
-- `env-docker/bin`
-
-Services data:
-
-- `/allura-data/mongo` - mongo data
-- `/allura-data/solr` - SOLR index
-- `/allura-data/scm/{git,hg,svn}` - code repositories
-- `/allura-data/scm/snapshots` - generated code snapshots
-
-## Ports, exposed to host system:
-
-- 8080 - webapp
-- 8983 - SOLR admin panel (http://localhost:8983/solr/)
-- 8825 - incoming mail listener
-
-
-# First run
-
-[Download the latest release](http://www.apache.org/dyn/closer.cgi/allura/) of Allura, or [clone from git](https://forge-allura.apache.org/p/allura/git/ci/master/tree/) for the bleeding edge.
-
-Install [Docker](http://docs.docker.com/installation/) and [Docker Compose](https://docs.docker.com/compose/install/).
-
-Build/fetch all required images (run these in your allura directory):
-
-    ~$ docker-compose build
-
-Install requirements:
-
-    ~$ docker-compose run web pip install -r requirements.txt
-
-Install Allura packages:
-
-    ~$ docker-compose run web ./rebuild-all.bash
-
-Initialize database with test data:
-
-    ~$ docker-compose run web bash -c 'cd Allura && paster setup-app docker-dev.ini'
-
-If you want to skip test data creation you can instead run:
-
-    ~$ docker-compose run web bash -c 'cd Allura && ALLURA_TEST_DATA=False paster setup-app docker-dev.ini'
-
-Start containers in background:
-
-    ~$ docker-compose up -d
-
-# Useful commands
-
-Restarting all containers:
-
-    ~$ docker-compose up -d
-
-View logs from all services:
-
-    ~$ docker-compose logs
-
-You can specify one or more services to view logs only from them, e.g. to see
-outgoing mail:
-
-    ~$ docker-compose logs outmail
-
-Update requirements and reinstall apps:
-
-    ~$ docker-compose run web pip install -r requirements.txt
-    ~$ docker-compose run web ./rebuild-all.bash
-
-You may want to restart at least taskd container after that in order for it to
-pick up changes.
-
-Running all tests:
-
-    ~$ docker-compose run web ./run_tests
-
-Running subset of tests:
-
-    ~$ docker-compose run web bash -c 'cd ForgeGit && nosetests forgegit.tests.functional.test_controllers:TestFork'
-
-Connecting to mongo directly:
-
-    ~$ docker-compose run mongo mongo --host mongo

http://git-wip-us.apache.org/repos/asf/allura/blob/a8ace0d5/INSTALL.markdown
----------------------------------------------------------------------
diff --git a/INSTALL.markdown b/INSTALL.markdown
index eab7dfd..57c0b89 100644
--- a/INSTALL.markdown
+++ b/INSTALL.markdown
@@ -17,156 +17,4 @@
     under the License.
 -->
 
-# Step-by-Step Installation
-
-For a simpler setup using Docker images, see INSTALL-docker.markdown instead.
-
-In these instructions, we'll use [VirtualBox](http://www.virtualbox.org) and [Ubuntu 14.04](http://ubuntu.com) (12.04 works too) to create a disposable sandbox for Allura development/testing.  Allura should work on other Linux systems (including OSX), but setting up all the dependencies will be different.
-
-* Download and install [VirtualBox](http://www.virtualbox.org/wiki/Downloads) for your platform.
-
-* Download a minimal [Ubuntu 14.04 64-bit ISO](https://help.ubuntu.com/community/Installation/MinimalCD).
-
-* Create a new virtual machine in Virtual Box, selecting Ubuntu (64 bit) as the OS type.  The rest of the wizards' defaults are fine.
-
-* When you launch the virtual machine for the first time, you will be prompted to attach your installation media.  Browse to the `mini.iso` that you downloaded earlier.
-
-* After a text-only installation, you may end up with a blank screen and blinking cursor.  Press Alt-F1 to switch to the first console.
-
-* Consult [available documentation](https://help.ubuntu.com/) for help installing Ubuntu.
-
-
-# Installation
-
-Before we begin, you'll need to install some system packages.
-
-    ~$ sudo aptitude install git-core default-jre-headless python-dev libssl-dev libldap2-dev libsasl2-dev libjpeg8-dev zlib1g-dev
-
-To install MongoDB, follow the instructions here: <http://docs.mongodb.org/v2.6/tutorial/install-mongodb-on-ubuntu/>
-
-Optional, for SVN support:
-
-    ~$ sudo aptitude install subversion python-svn
-
-## Setting up a virtual python environment
-
-The first step to installing the Allura platform is installing a virtual environment via `virtualenv`.  This helps keep our distribution python installation clean.
-
-    ~$ sudo aptitude install python-pip
-    ~$ sudo pip install virtualenv
-
-Once you have virtualenv installed, you need to create a virtual environment.  We'll call our Allura environment 'env-allura'.
-
-    ~$ virtualenv env-allura
-
-This gives us a nice, clean environment into which we can install all the allura dependencies.
-In order to use the virtual environment, you'll need to activate it:
-
-    ~$ . env-allura/bin/activate
-
-You'll need to do this whenever you're working on the Allura codebase so you may want to consider adding it to your `~/.bashrc` file.
-
-## Creating the log directory
-    (env-allura)~$ sudo mkdir -p /var/log/allura
-    (env-allura)~$ sudo chown $(whoami) /var/log/allura
-
-## Installing the Allura code and dependencies
-
-Now we can get down to actually getting the Allura code and dependencies downloaded and ready to go.  If you don't have the source code yet, run:
-
-    (env-allura)~$ mkdir src
-    (env-allura)~$ cd src
-    (env-allura)~/src$ git clone https://git-wip-us.apache.org/repos/asf/allura.git allura
-
-If you already reading this file from an Allura release or checkout, you're ready to continue.
-
-Although the application setup.py files define a number of dependencies, the `requirements.txt` files are currently the authoritative source, so we'll use those with `pip` to make sure the correct versions are installed.
-
-    (env-allura)~/src$ cd allura
-    (env-allura)~/src/allura$ pip install -r requirements.txt
-
-This will take a while.  If you get an error from pip, it is typically a temporary download error.  Just run the command again and it will quickly pass through the packages it already downloaded and then continue.
-
-Optional, for SVN support: symlink the system pysvn package into our virtual environment
-
-    (env-allura)~/src/allura$ ln -s /usr/lib/python2.7/dist-packages/pysvn ~/env-allura/lib/python2.7/site-packages/
-
-Next, run `./rebuild-all.bash` to setup all the Allura applications.  If you only want to use a few tools, run:
-
-    cd Allura
-    python setup.py develop
-    cd ../ForgeWiki   # required tool
-    python setup.py develop
-    # repeat for any other tools you want to use
-
-## Initializing the environment
-
-The Allura forge consists of several components, all of which need to be running to have full functionality.
-
-### SOLR search and indexing server
-
-We have a custom config ready for use.
-
-    (env-allura)~$ cd ~/src
-    (env-allura)~/src$ wget -nv http://archive.apache.org/dist/lucene/solr/4.2.1/solr-4.2.1.tgz
-    (env-allura)~/src$ tar xf solr-4.2.1.tgz && rm -f solr-4.2.1.tgz
-    (env-allura)~/src$ cp -f allura/solr_config/schema.xml solr-4.2.1/example/solr/collection1/conf
-
-    (env-allura)~/src$ cd solr-4.2.1/example/
-    (env-allura)~/src/apache-solr-4.2.1/example/$ nohup java -jar start.jar > /var/log/allura/solr.log &
-
-
-### Create code repo directories
-
-The default configuration stores repos in `/srv`, so we need to create those directories:
-
-    sudo mkdir /srv/{git,svn,hg}
-    sudo chown $USER /srv/{git,svn,hg}
-    sudo chmod 775 /srv/{git,svn,hg}
-
-If you don't have `sudo` permission or just want to store them somewhere else, change the `/srv` paths in `development.ini`
-
-If you want to set up remote access to the repositories, see <http://forge-allura.apache.org/docs/getting_started/scm_host.html>
-
-### Allura task processing
-
-Allura uses a background task service called "taskd" to do async tasks like sending emails, and indexing data into solr, etc.  Let's get it running
-
-    (env-allura)~$ cd ~/src/allura/Allura
-    (env-allura)~/src/allura/Allura$ nohup paster taskd development.ini > /var/log/allura/taskd.log 2>&1 &
-
-### The application server
-
-In order to initialize the Allura database, you'll need to run the following:
-
-For development setup:
-
-    (env-allura)~/src/allura/Allura$ paster setup-app development.ini
-
-For production setup:
-
-    (env-allura)~/src/allura/Allura$ ALLURA_TEST_DATA=False paster setup-app development.ini
-
-This shouldn't take too long, but it will start the taskd server doing tons of stuff in the background.  Once this is done, you can start the application server:
-
-    (env-allura)~/src/allura/Allura$ nohup paster serve --reload development.ini  > /var/log/allura/allura.log 2>&1 &
-
-## Next Steps
-
-Go to the Allura webapp running on your [local machine](http://localhost:8080/) port 8080.
-(If you're running this inside a VM, you'll probably have to configure the port forwarding settings)
-
-You can log in with username admin1, test-user or root.  They all have password "foo".  (For more details
-on the default data, see bootstrap.py)
-
-There are a few default projects (like "test") and neighborhoods.  Feel free to experiment with them.  If you want to
-register a new project in your own forge, visit /p/add_project
-
-## Extra
-
-* Read more documentation: <http://forge-allura.apache.org/docs/>
-    * Including how to enable extra features: <http://forge-allura.apache.org/docs/getting_started/installation.html>
-* Ask questions and discuss Allura on the <http://mail-archives.apache.org/mod_mbox/allura-dev/>
-* Run the test suite (slow): `$ ALLURA_VALIDATION=none ./run_tests`
-* File bug reports at <https://forge-allura.apache.org/p/allura/tickets/new/> (login required)
-* Contribute code according to this guide: <https://forge-allura.apache.org/p/allura/wiki/Contributing%20Code/>
+See `Allura/docs`.

http://git-wip-us.apache.org/repos/asf/allura/blob/a8ace0d5/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 69af9fe..fb04ff5 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Allura
-Copyright 2012-2014 The Apache Software Foundation
+Copyright 2012-2015 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

http://git-wip-us.apache.org/repos/asf/allura/blob/a8ace0d5/README.markdown
----------------------------------------------------------------------
diff --git a/README.markdown b/README.markdown
index 5daeb0c..5eec88f 100644
--- a/README.markdown
+++ b/README.markdown
@@ -22,7 +22,7 @@ Apache Allura
 
 Allura is an open source implementation of a software "forge", a web site that manages source code repositories, bug reports, discussions, mailing lists, wiki pages, blogs and more for any number of individual projects.
 
-To install Allura, see INSTALL.markdown
+To install Allura, see `Allura/docs`.
 
 Website: <https://allura.apache.org/>
 


[50/50] [abbrv] allura git commit: [#7925] Git tree command flags now support older versions of git

Posted by he...@apache.org.
[#7925] Git tree command flags now support older versions of git


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/4090d3be
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/4090d3be
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/4090d3be

Branch: refs/heads/hs/7925
Commit: 4090d3be84f56fff9a4739e8d0e97eaaece7b4cb
Parents: d8e7ade
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Mon Aug 10 13:31:52 2015 -0400
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 13:31:52 2015 -0400

----------------------------------------------------------------------
 ForgeGit/forgegit/model/git_repo.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/4090d3be/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 318f81f..480631b 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -646,8 +646,8 @@ class GitImplementation(M.RepositoryImplementation):
 
         cmd_output = self._git.git.diff_tree(
             '--no-commit-id',
-            '--find-renames',
-            '--find-copies',
+            '-M',  # detect renames
+            '-C',  # detect copies
             '--name-status',
             '--no-abbrev',
             '--root',


[49/50] [abbrv] allura git commit: [#7925] use frozensets for faster O(1) checking of file extensions

Posted by he...@apache.org.
[#7925] use frozensets for faster O(1) checking of file extensions


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d8e7ade5
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d8e7ade5
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d8e7ade5

Branch: refs/heads/hs/7925
Commit: d8e7ade5d7ec8fa35d09b4d2cb2a4ee2aa54bb29
Parents: 46baba1
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Aug 7 18:04:45 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:38 2015 -0400

----------------------------------------------------------------------
 Allura/allura/model/repository.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d8e7ade5/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index acbc3d1..77c3fc4 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -65,10 +65,10 @@ config = utils.ConfigProxy(
     common_prefix='forgemail.url')
 
 README_RE = re.compile('^README(\.[^.]*)?$', re.IGNORECASE)
-VIEWABLE_EXTENSIONS = [
+VIEWABLE_EXTENSIONS = frozenset([
     '.php', '.py', '.js', '.java', '.html', '.htm', '.yaml', '.sh',
     '.rb', '.phtml', '.txt', '.bat', '.ps1', '.xhtml', '.css', '.cfm', '.jsp', '.jspx',
-    '.pl', '.php4', '.php3', '.rhtml', '.svg', '.markdown', '.json', '.ini', '.tcl', '.vbs', '.xsl']
+    '.pl', '.php4', '.php3', '.rhtml', '.svg', '.markdown', '.json', '.ini', '.tcl', '.vbs', '.xsl'])
 
 
 # Some schema types
@@ -77,7 +77,7 @@ SObjType = S.OneOf('blob', 'tree', 'submodule')
 
 # Used for when we're going to batch queries using $in
 QSIZE = 100
-BINARY_EXTENSIONS = [
+BINARY_EXTENSIONS = frozenset([
     ".3ds", ".3g2", ".3gp", ".7z", ".a", ".aac", ".adp", ".ai", ".aif", ".apk", ".ar", ".asf", ".au", ".avi",
     ".bak", ".bin", ".bk", ".bmp", ".btif", ".bz2", ".cab", ".caf", ".cgm", ".cmx", ".cpio", ".cr2", ".dat", ".deb", ".djvu", ".dll",
     ".dmg", ".dng", ".doc", ".docx", ".dra", ".DS_Store", ".dsk", ".dts", ".dtshd", ".dvb", ".dwg", ".dxf", ".ecelp4800",
@@ -90,9 +90,9 @@ BINARY_EXTENSIONS = [
     ".smv", ".so", ".sub", ".swf", ".tar", ".tbz2", ".tga", ".tgz", ".tif", ".tiff", ".tlz", ".ts", ".ttf", ".uvh", ".uvi", ".uvm",
     ".uvp", ".uvs", ".uvu", ".viv", ".vob", ".war", ".wav", ".wax", ".wbmp", ".wdp", ".weba", ".webm", ".webp", ".whl", ".wm", ".wma",
     ".wmv", ".wmx", ".woff", ".woff2", ".wvx", ".xbm", ".xif", ".xm", ".xpi", ".xpm", ".xwd", ".xz", ".z", ".zip", ".zipx"
-]
+])
 
-PYPELINE_EXTENSIONS = utils.MARKDOWN_EXTENSIONS + ['.rst']
+PYPELINE_EXTENSIONS = frozenset(utils.MARKDOWN_EXTENSIONS + ['.rst'])
 
 DIFF_SIMILARITY_THRESHOLD = .5  # used for determining file renames
 


[27/50] [abbrv] allura git commit: CHANGES updated for ASF release 1.3.1

Posted by he...@apache.org.
CHANGES updated for ASF release 1.3.1


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d07cd701
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d07cd701
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d07cd701

Branch: refs/heads/hs/7925
Commit: d07cd7017b7ba1f08879babad3db8ad9fb92d7b4
Parents: acd5b12
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Aug 5 18:32:25 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Aug 5 18:32:25 2015 -0400

----------------------------------------------------------------------
 CHANGES | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d07cd701/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 5f4f0a9..917fd37 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,58 @@
+Version 1.3.1  (August 2015)
+
+Upgrade Instructions
+
+ To enable CORS headers for the rest APIs, use the cors.* settings in the development.ini file.
+ If you have your own .ini file, enable git tag & branch caching speedups by setting: repo_refs_cache_threshold = .01
+
+New Features
+
+ * [#5943] Post-setup instructions
+ * [#6373] Document administrative commands
+ * [#7897] Live syntax highlighting for markdown editing
+ * [#7927] Allow CORS access to rest APIs
+ * [#7540] Ticket notifications should include links to attachments
+
+Security
+
+ * [#7947] XSS vulnerability in link rewriting
+ * [#7942] In project admin - user permissions, removing a custom group needs to use POST
+ * [#7685] Subscribe/unsubscribe action should use POST
+
+Bug Fixes & Minor Improvements
+
+ Tickets:
+ * [#4020] Date picker in milestone editor doesn't flip between months
+ Wiki:
+ * [#4802] Wiki edit link is not very discoverable
+ * [#7310] "Maximize" should stick
+ Code repositories:
+ * [#7873] Git branch & tag speedups  -- NEEDS INI
+ * [#7894] Don't update merge request timestamps incorrectly
+ * [#7932] Fix pagination issue in the commit browser
+ * [#7899] Issue with downloading files from repo with spaces in name
+ * [#7906] Fix login check on ApacheAccessHandler.py
+ Forums:
+ * [#7880] Forums mail not getting sent that require moderation
+ * [#7930] Bug: viewing a thread updates project mod_date
+ Project Admin:
+ * [#7884] Move add/edit Features to Metadata section
+ * [#7885] Tooltip for project admin
+ * [#7898] Icon upload/edit is not clear
+ General:
+ * [#7803] Fix taskd_cleanup to search for right process name
+ * [#7889] Improve markdown logic for cached vs threshold limits
+ * [#7890] Neighborhood cache preventing saving admin changes
+ * [#7916] Error when handling user-profile URLs of users with invalid names.
+ * [#7928] Site admin search tables can overflow the page width
+ * [#7903] No mention about small letters in user registration
+ * [#7909] Use dashes when suggesting project shortnames
+ * [#7915] Move Allura installation instructions into the docs
+ For Developers:
+ * [#7809] Update install/docker to ubuntu 14.04
+ * [#7891] Remove zarkov integration code
+
+
 Version 1.3.0  (June 2015)
 
 Upgrade Instructions


[38/50] [abbrv] allura git commit: [#7925] fix looping/delete bug

Posted by he...@apache.org.
[#7925] fix looping/delete bug


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/787ee906
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/787ee906
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/787ee906

Branch: refs/heads/hs/7925
Commit: 787ee906ab185dcee0193bd412b5cc4bab252cbd
Parents: 155e0b0
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 16:10:38 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:36 2015 -0400

----------------------------------------------------------------------
 ForgeSVN/forgesvn/model/svn.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/787ee906/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index f43f536..b9d986e 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -817,8 +817,8 @@ class SVNImplementation(M.RepositoryImplementation):
                 # svn commit -m "Replace aaa.txt"
                 result['changed'].append(h.really_unicode(p.path))
 
-        for r in result['copied']:
-            if r['old'] in result['removed'][:]:
+        for r in result['copied'][:]:
+            if r['old'] in result['removed']:
                 result['removed'].remove(r['old'])
                 result['copied'].remove(r)
                 result['renamed'].append(r)


[48/50] [abbrv] allura git commit: [#7925] join split lines into one again. We're ok >79 chars

Posted by he...@apache.org.
[#7925] join split lines into one again.  We're ok >79 chars


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/5ac9651f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/5ac9651f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/5ac9651f

Branch: refs/heads/hs/7925
Commit: 5ac9651fa789d9fbf762a08375145b0d622acc2b
Parents: 9639112
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Aug 4 20:32:26 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:38 2015 -0400

----------------------------------------------------------------------
 Allura/allura/tests/model/test_repo.py | 121 +++++++++-------------------
 1 file changed, 39 insertions(+), 82 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5ac9651f/Allura/allura/tests/model/test_repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py
index c0a6bc8..9b364aa 100644
--- a/Allura/allura/tests/model/test_repo.py
+++ b/Allura/allura/tests/model/test_repo.py
@@ -32,7 +32,6 @@ from allura.lib import helpers as h
 
 
 class TestGitLikeTree(object):
-
     def test_set_blob(self):
         tree = M.GitLikeTree()
         tree.set_blob('/dir/dir2/file', 'file-oid')
@@ -63,7 +62,6 @@ class TestGitLikeTree(object):
 
 
 class RepoImplTestBase(object):
-
     def test_commit_run(self):
         M.repository.CommitRunDoc.m.remove()
         commit_ids = list(self.repo.all_commit_ids())
@@ -100,7 +98,6 @@ class RepoImplTestBase(object):
 
 
 class RepoTestBase(unittest.TestCase):
-
     def setUp(self):
         setup_basic_test()
 
@@ -131,7 +128,6 @@ class RepoTestBase(unittest.TestCase):
 
 
 class TestLastCommit(unittest.TestCase):
-
     def setUp(self):
         setup_basic_test()
         setup_global_objects()
@@ -168,6 +164,7 @@ class TestLastCommit(unittest.TestCase):
             m = mock.Mock()
             m.name = p
             return m
+
         for p in tree_paths:
             if '/' in p:
                 node, sub = p.split('/', 1)
@@ -222,8 +219,7 @@ class TestLastCommit(unittest.TestCase):
             'dir1/file2',
         ])
         lcd = M.repository.LastCommit.get(commit1.tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit1.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit1.message)
         self.assertEqual(lcd.path, '')
         self.assertEqual(len(lcd.entries), 2)
         self.assertEqual(lcd.by_name['file1'], commit1._id)
@@ -231,13 +227,10 @@ class TestLastCommit(unittest.TestCase):
 
     def test_multiple_commits_no_overlap(self):
         commit1 = self._add_commit('Commit 1', ['file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'file2'], ['file2'], [commit2])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'file2'], ['file2'], [commit2])
         lcd = M.repository.LastCommit.get(commit3.tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit3.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit3.message)
         self.assertEqual(lcd.commit_id, commit3._id)
         self.assertEqual(lcd.path, '')
         self.assertEqual(len(lcd.entries), 3)
@@ -247,13 +240,10 @@ class TestLastCommit(unittest.TestCase):
 
     def test_multiple_commits_with_overlap(self):
         commit1 = self._add_commit('Commit 1', ['file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'file2'], ['file1', 'file2'], [commit2])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'file2'], ['file1', 'file2'], [commit2])
         lcd = M.repository.LastCommit.get(commit3.tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit3.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit3.message)
         self.assertEqual(lcd.path, '')
         self.assertEqual(len(lcd.entries), 3)
         self.assertEqual(lcd.by_name['file1'], commit3._id)
@@ -262,13 +252,10 @@ class TestLastCommit(unittest.TestCase):
 
     def test_multiple_commits_subdir_change(self):
         commit1 = self._add_commit('Commit 1', ['file1', 'dir1/file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file1'], [commit2])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file1'], [commit2])
         lcd = M.repository.LastCommit.get(commit3.tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit3.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit3.message)
         self.assertEqual(lcd.path, '')
         self.assertEqual(len(lcd.entries), 2)
         self.assertEqual(lcd.by_name['file1'], commit1._id)
@@ -276,14 +263,11 @@ class TestLastCommit(unittest.TestCase):
 
     def test_subdir_lcd(self):
         commit1 = self._add_commit('Commit 1', ['file1', 'dir1/file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file1'], [commit2])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file1'], [commit2])
         tree = self._build_tree(commit3, '/dir1', ['file1', 'file2'])
         lcd = M.repository.LastCommit.get(tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit3.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit3.message)
         self.assertEqual(lcd.path, 'dir1')
         self.assertEqual(len(lcd.entries), 2)
         self.assertEqual(lcd.by_name['file1'], commit3._id)
@@ -291,16 +275,12 @@ class TestLastCommit(unittest.TestCase):
 
     def test_subdir_lcd_prev_commit(self):
         commit1 = self._add_commit('Commit 1', ['file1', 'dir1/file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file1'], [commit2])
-        commit4 = self._add_commit(
-            'Commit 4', ['file1', 'dir1/file1', 'dir1/file2', 'file2'], ['file2'], [commit3])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file1'], [commit2])
+        commit4 = self._add_commit('Commit 4', ['file1', 'dir1/file1', 'dir1/file2', 'file2'], ['file2'], [commit3])
         tree = self._build_tree(commit4, '/dir1', ['file1', 'file2'])
         lcd = M.repository.LastCommit.get(tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit3.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit3.message)
         self.assertEqual(lcd.path, 'dir1')
         self.assertEqual(len(lcd.entries), 2)
         self.assertEqual(lcd.by_name['file1'], commit3._id)
@@ -308,32 +288,26 @@ class TestLastCommit(unittest.TestCase):
 
     def test_subdir_lcd_always_empty(self):
         commit1 = self._add_commit('Commit 1', ['file1', 'dir1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'file2'], ['file2'], [commit1])
+        commit2 = self._add_commit('Commit 2', ['file1', 'file2'], ['file2'], [commit1])
         tree = self._build_tree(commit2, '/dir1', [])
         lcd = M.repository.LastCommit.get(tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit1.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit1.message)
         self.assertEqual(lcd.path, 'dir1')
         self.assertEqual(lcd.entries, [])
 
     def test_subdir_lcd_emptied(self):
         commit1 = self._add_commit('Commit 1', ['file1', 'dir1/file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1'], ['dir1/file1'], [commit1])
+        commit2 = self._add_commit('Commit 2', ['file1'], ['dir1/file1'], [commit1])
         tree = self._build_tree(commit2, '/dir1', [])
         lcd = M.repository.LastCommit.get(tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit2.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit2.message)
         self.assertEqual(lcd.path, 'dir1')
         self.assertEqual(lcd.entries, [])
 
     def test_existing_lcd_unchained(self):
         commit1 = self._add_commit('Commit 1', ['file1', 'dir1/file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['file1'], [commit2])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1', 'dir1/file2'], ['dir1/file2'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'dir1/file2'], ['file1'], [commit2])
         prev_lcd = M.repository.LastCommit(
             path='dir1',
             commit_id=commit2._id,
@@ -350,19 +324,15 @@ class TestLastCommit(unittest.TestCase):
         tree = self._build_tree(commit3, '/dir1', ['file1', 'file2'])
         lcd = M.repository.LastCommit.get(tree)
         self.assertEqual(lcd._id, prev_lcd._id)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit2.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit2.message)
         self.assertEqual(lcd.path, 'dir1')
         self.assertEqual(lcd.entries, prev_lcd.entries)
 
     def test_existing_lcd_partial(self):
         commit1 = self._add_commit('Commit 1', ['file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'file2'], ['file2'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'file2', 'file3'], ['file3'], [commit2])
-        commit4 = self._add_commit(
-            'Commit 4', ['file1', 'file2', 'file3', 'file4'], ['file2', 'file4'], [commit3])
+        commit2 = self._add_commit('Commit 2', ['file1', 'file2'], ['file2'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'file2', 'file3'], ['file3'], [commit2])
+        commit4 = self._add_commit('Commit 4', ['file1', 'file2', 'file3', 'file4'], ['file2', 'file4'], [commit3])
         prev_lcd = M.repository.LastCommit(
             path='',
             commit_id=commit3._id,
@@ -380,8 +350,7 @@ class TestLastCommit(unittest.TestCase):
         )
         session(prev_lcd).flush()
         lcd = M.repository.LastCommit.get(commit4.tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit4.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit4.message)
         self.assertEqual(lcd.path, '')
         self.assertEqual(len(lcd.entries), 4)
         self.assertEqual(lcd.by_name['file1'], commit1._id)
@@ -404,14 +373,11 @@ class TestLastCommit(unittest.TestCase):
 
     def test_timeout(self):
         commit1 = self._add_commit('Commit 1', ['file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'file2'], ['file2'], [commit2])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'file2'], ['file2'], [commit2])
         with h.push_config(config, lcd_timeout=-1000):
             lcd = M.repository.LastCommit.get(commit3.tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit3.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit3.message)
         self.assertEqual(lcd.commit_id, commit3._id)
         self.assertEqual(lcd.path, '')
         self.assertEqual(len(lcd.entries), 1)
@@ -419,15 +385,12 @@ class TestLastCommit(unittest.TestCase):
 
     def test_loop(self):
         commit1 = self._add_commit('Commit 1', ['file1'])
-        commit2 = self._add_commit(
-            'Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
-        commit3 = self._add_commit(
-            'Commit 3', ['file1', 'dir1/file1', 'file2'], ['file2'], [commit2])
+        commit2 = self._add_commit('Commit 2', ['file1', 'dir1/file1'], ['dir1/file1'], [commit1])
+        commit3 = self._add_commit('Commit 3', ['file1', 'dir1/file1', 'file2'], ['file2'], [commit2])
         commit2.parent_ids = [commit3._id]
         session(commit2).flush(commit2)
         lcd = M.repository.LastCommit.get(commit3.tree)
-        self.assertEqual(
-            self.repo._commits[lcd.commit_id].message, commit3.message)
+        self.assertEqual(self.repo._commits[lcd.commit_id].message, commit3.message)
         self.assertEqual(lcd.commit_id, commit3._id)
         self.assertEqual(lcd.path, '')
         self.assertEqual(len(lcd.entries), 3)
@@ -436,7 +399,6 @@ class TestLastCommit(unittest.TestCase):
 
 
 class TestModelCache(unittest.TestCase):
-
     def setUp(self):
         self.cache = M.repository.ModelCache()
 
@@ -510,15 +472,11 @@ class TestModelCache(unittest.TestCase):
         self.assertEqual(self.cache._instance_cache,
                          {M.repository.Tree: {'OBJID': tree}})
         tree._id = '_id'
-        self.assertEqual(
-            self.cache.get(M.repository.Tree, {'val1': 'test_set1'}), tree)
-        self.assertEqual(
-            self.cache.get(M.repository.Tree, {'val2': 'test_set2'}), tree)
+        self.assertEqual(self.cache.get(M.repository.Tree, {'val1': 'test_set1'}), tree)
+        self.assertEqual(self.cache.get(M.repository.Tree, {'val2': 'test_set2'}), tree)
         self.cache.set(M.repository.Tree, {'val1': 'test_set2'}, tree)
-        self.assertEqual(
-            self.cache.get(M.repository.Tree, {'val1': 'test_set1'}), tree)
-        self.assertEqual(
-            self.cache.get(M.repository.Tree, {'val2': 'test_set2'}), tree)
+        self.assertEqual(self.cache.get(M.repository.Tree, {'val1': 'test_set1'}), tree)
+        self.assertEqual(self.cache.get(M.repository.Tree, {'val2': 'test_set2'}), tree)
 
     @mock.patch('bson.ObjectId')
     def test_set_none_val(self, obj_id):
@@ -727,7 +685,6 @@ class TestModelCache(unittest.TestCase):
 
 
 class TestMergeRequest(object):
-
     def setUp(self):
         setup_basic_test()
         setup_global_objects()


[18/50] [abbrv] allura git commit: [#7947] use beautifulsoup4 for correct identification of tricky tag situations during URL rewriting

Posted by he...@apache.org.
[#7947] use beautifulsoup4 for correct identification of tricky tag situations during URL rewriting


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e0e2f0c4
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e0e2f0c4
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e0e2f0c4

Branch: refs/heads/hs/7925
Commit: e0e2f0c4057a33256d59da72c73626848a1d6579
Parents: 556a99e
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Aug 3 18:45:36 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Aug 3 18:55:26 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/markdown_extensions.py | 17 ++++++-----------
 Allura/allura/tests/test_globals.py      |  7 +++++++
 requirements.txt                         |  3 ++-
 3 files changed, 15 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e0e2f0c4/Allura/allura/lib/markdown_extensions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/markdown_extensions.py b/Allura/allura/lib/markdown_extensions.py
index 83e8069..cbccf5d 100644
--- a/Allura/allura/lib/markdown_extensions.py
+++ b/Allura/allura/lib/markdown_extensions.py
@@ -20,7 +20,7 @@ import logging
 from urlparse import urljoin
 
 from tg import config
-from BeautifulSoup import BeautifulSoup
+from bs4 import BeautifulSoup
 import html5lib
 import html5lib.serializer
 import html5lib.filters.alphabeticalattributes
@@ -441,7 +441,8 @@ class RelativeLinkRewriter(markdown.postprocessors.Postprocessor):
         self._make_absolute = make_absolute
 
     def run(self, text):
-        soup = BeautifulSoup(text)
+        soup = BeautifulSoup(text, 'html5lib')  # 'html.parser' parser gives weird </li> behaviour with test_macro_members
+
         if self._make_absolute:
             rewrite = self._rewrite_abs
         else:
@@ -450,15 +451,9 @@ class RelativeLinkRewriter(markdown.postprocessors.Postprocessor):
             rewrite(link, 'href')
         for link in soup.findAll('img'):
             rewrite(link, 'src')
-        # BeautifulSoup always stores data in unicode,
-        # but when doing unicode(soup) it does some strange things
-        # like nesting html comments, e.g. returns <!--<!-- comment -->-->
-        # instead of <!-- comment -->.
-        # Converting soup object to string representation first,
-        # and then back to unicode avoids that.
-        # str() called on BeautifulSoup document always returns string
-        # encoded in utf-8, so this should always work.
-        return h.really_unicode(str(soup))
+
+        # html5lib parser adds html/head/body tags, so output <body> without its own tags
+        return unicode(soup.body)[len('<body>'):-len('</body>')]
 
     def _rewrite(self, tag, attr):
         val = tag.get(attr)

http://git-wip-us.apache.org/repos/asf/allura/blob/e0e2f0c4/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index ca04652..91565ae 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -480,6 +480,13 @@ def test_markdown_invalid_tagslash():
     r = g.markdown.convert('<div/onload><img src=x onerror=alert(document.cookie)>')
     assert_not_in('onerror', r)
 
+def test_markdown_invalid_script_in_link():
+    r = g.markdown.convert('[xss](http://"><a onmouseover=prompt(document.domain)>xss</a>)')
+    assert_equal('''<div class="markdown_content"><p><a class="" href='http://"&gt;&lt;a%20onmouseover=prompt(document.domain)&gt;xss&lt;/a&gt;' rel="nofollow">xss</a></p></div>''', r)
+
+def test_markdown_invalid_script_in_link2():
+    r = g.markdown.convert('[xss](http://"><img src=x onerror=alert(document.cookie)>)')
+    assert_equal('''<div class="markdown_content"><p><a class="" href='http://"&gt;&lt;img%20src=x%20onerror=alert(document.cookie)&gt;' rel="nofollow">xss</a></p></div>''', r)
 
 @td.with_wiki
 def test_macro_include():

http://git-wip-us.apache.org/repos/asf/allura/blob/e0e2f0c4/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index 77581e2..d327584 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
 ActivityStream==0.2.0
 BeautifulSoup==3.2.0
+BeautifulSoup4==4.4.0
 Beaker==1.6.4
 chardet==1.0.1
 colander==0.9.3
@@ -81,4 +82,4 @@ q==2.3
 WebError==0.10.3
 -e git://github.com/brondsem/sphinx-argparse.git#egg=sphinx-argparse   # pending merge requests
 sphinx-rtd-theme==0.1.6
-sphinxcontrib-programoutput==0.8
\ No newline at end of file
+sphinxcontrib-programoutput==0.8


[05/50] [abbrv] allura git commit: [#7897] ticket:823 Fixed-width font for preformatted text in the preview

Posted by he...@apache.org.
[#7897] ticket:823 Fixed-width font for preformatted text in the preview


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/eaba4773
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/eaba4773
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/eaba4773

Branch: refs/heads/hs/7925
Commit: eaba4773bb642fcc94d683fa1b350cbcf1f4f600
Parents: cb8e49f
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 17 17:12:52 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/css/markitup_sf.css | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/eaba4773/Allura/allura/lib/widgets/resources/css/markitup_sf.css
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/css/markitup_sf.css b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
index c673765..5dd88cd 100644
--- a/Allura/allura/lib/widgets/resources/css/markitup_sf.css
+++ b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
@@ -39,6 +39,9 @@
 .markdown_edit .editor-preview {
   z-index: 1001;  /* should always be under help modal */
 }
+.markdown_edit .editor-preview pre {
+  font-family: monospace;
+}
 .markdown_edit .editor-preview-active {
   background-color: transparent;
   position: relative;


[07/50] [abbrv] allura git commit: [#7897] ticket:820 Add top and bottom margins to separate editor from buttons

Posted by he...@apache.org.
[#7897] ticket:820 Add top and bottom margins to separate editor from buttons


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/42b50145
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/42b50145
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/42b50145

Branch: refs/heads/hs/7925
Commit: 42b501457fd48fbb31f65520efc3ebe2b8f24341
Parents: 19b0683
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Jul 14 17:27:51 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/css/markitup_sf.css | 2 ++
 ForgeWiki/forgewiki/templates/wiki/page_edit.html       | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/42b50145/Allura/allura/lib/widgets/resources/css/markitup_sf.css
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/css/markitup_sf.css b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
index 059721a..c673765 100644
--- a/Allura/allura/lib/widgets/resources/css/markitup_sf.css
+++ b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
@@ -19,6 +19,8 @@
 .markdown_edit {
   width: 95%;
   background: white;
+  margin-top: 5px;
+  margin-bottom: 5px;
 }
 .markdown_edit .CodeMirror {
   min-height: 120px;

http://git-wip-us.apache.org/repos/asf/allura/blob/42b50145/ForgeWiki/forgewiki/templates/wiki/page_edit.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_edit.html b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
index 2bcb94b..fa0e95e 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_edit.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
@@ -64,11 +64,9 @@
 	  {{c.markdown_editor.display(id='text', name='text',value=page.text)}}
 	</div>
 	<div style="clear:both;"></div>
-  <div style="margin-top: 1em;">
 	<label class="grid-4">Labels:</label>
 	<div class="grid-14" style="margin-left:0">
 		{{c.label_edit.display(id='labels', name='labels', value=page.labels)}}
-	</div>
   </div>
   <div class="grid-19">
     <input type="submit" value="Save">


[20/50] [abbrv] allura git commit: [#7947] fix7528 was bool, now its int

Posted by he...@apache.org.
[#7947] fix7528 was bool, now its int


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/cc5f2ac6
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/cc5f2ac6
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/cc5f2ac6

Branch: refs/heads/hs/7925
Commit: cc5f2ac60499ea89633bff2dd2a08ddb06a9b74a
Parents: ad029f8
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Aug 3 20:25:24 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Aug 3 20:25:24 2015 +0000

----------------------------------------------------------------------
 Allura/allura/model/types.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/cc5f2ac6/Allura/allura/model/types.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/types.py b/Allura/allura/model/types.py
index 6a8ff71..833e685 100644
--- a/Allura/allura/model/types.py
+++ b/Allura/allura/model/types.py
@@ -27,7 +27,7 @@ class MarkdownCache(S.Object):
         super(MarkdownCache, self).__init__(
             fields=dict(
                 md5=S.String(),
-                fix7528=S.Bool,
+                fix7528=S.Anything,
                 html=S.String(),
                 render_time=S.Float()),
             **kw)


[45/50] [abbrv] allura git commit: [#7925] tests, fix, and docstring for has_html_view

Posted by he...@apache.org.
[#7925] tests, fix, and docstring for has_html_view


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/7133cb19
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/7133cb19
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/7133cb19

Branch: refs/heads/hs/7925
Commit: 7133cb19b3b770f45159ceacc968e85464599af4
Parents: 9835504
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 20:25:09 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:37 2015 -0400

----------------------------------------------------------------------
 Allura/allura/model/repository.py     | 28 +++++++++++++++-----------
 Allura/allura/tests/unit/test_repo.py | 32 +++++++++++++++++++++++++-----
 2 files changed, 43 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/7133cb19/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 636d10c..3db43a8 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -78,18 +78,18 @@ SObjType = S.OneOf('blob', 'tree', 'submodule')
 # Used for when we're going to batch queries using $in
 QSIZE = 100
 BINARY_EXTENSIONS = [
-    "3ds", "3g2", "3gp", "7z", "a", "aac", "adp", "ai", "aif", "apk", "ar", "asf", "au", "avi",
-    "bak", "bin", "bk", "bmp", "btif", "bz2", "cab", "caf", "cgm", "cmx", "cpio", "cr2", "dat", "deb", "djvu", "dll",
-    "dmg", "dng", "doc", "docx", "dra", "DS_Store", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ecelp4800",
-    "ecelp7470", "ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "fli", "flv",
-    "fpx", "fst", "fvt", "g3", "gif", "gz", "h261", "h263", "h264", "ico", "ief", "img", "ipa", "iso", "jar", "jpeg",
-    "jpg", "jpgv", "jpm", "jxr", "ktx", "lvp", "lz", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mid", "mj2",
-    "mka", "mkv", "mmr", "mng", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "mxu", "nef", "npx", "o",
-    "oga", "ogg", "ogv", "otf", "pbm", "pcx", "pdf", "pea", "pgm", "pic", "png", "pnm", "ppm", "psd", "pya", "pyc",
-    "pyo", "pyv", "qt", "rar", "ras", "raw", "rgb", "rip", "rlc", "rz", "s3m", "s7z", "scpt", "sgi", "shar", "sil",
-    "smv", "so", "sub", "swf", "tar", "tbz2", "tga", "tgz", "tif", "tiff", "tlz", "ts", "ttf", "uvh", "uvi", "uvm",
-    "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wm", "wma",
-    "wmv", "wmx", "woff", "woff2", "wvx", "xbm", "xif", "xm", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx"
+    ".3ds", ".3g2", ".3gp", ".7z", ".a", ".aac", ".adp", ".ai", ".aif", ".apk", ".ar", ".asf", ".au", ".avi",
+    ".bak", ".bin", ".bk", ".bmp", ".btif", ".bz2", ".cab", ".caf", ".cgm", ".cmx", ".cpio", ".cr2", ".dat", ".deb", ".djvu", ".dll",
+    ".dmg", ".dng", ".doc", ".docx", ".dra", ".DS_Store", ".dsk", ".dts", ".dtshd", ".dvb", ".dwg", ".dxf", ".ecelp4800",
+    ".ecelp7470", ".ecelp9600", ".egg", ".eol", ".eot", ".epub", ".exe", ".f4v", ".fbs", ".fh", ".fla", ".flac", ".fli", ".flv",
+    ".fpx", ".fst", ".fvt", ".g3", ".gif", ".gz", ".h261", ".h263", ".h264", ".ico", ".ief", ".img", ".ipa", ".iso", ".jar", ".jpeg",
+    ".jpg", ".jpgv", ".jpm", ".jxr", ".ktx", ".lvp", ".lz", ".lzma", ".lzo", ".m3u", ".m4a", ".m4v", ".mar", ".mdi", ".mid", ".mj2",
+    ".mka", ".mkv", ".mmr", ".mng", ".mov", ".movie", ".mp3", ".mp4", ".mp4a", ".mpeg", ".mpg", ".mpga", ".mxu", ".nef", ".npx", ".o",
+    ".oga", ".ogg", ".ogv", ".otf", ".pbm", ".pcx", ".pdf", ".pea", ".pgm", ".pic", ".png", ".pnm", ".ppm", ".psd", ".pya", ".pyc",
+    ".pyo", ".pyv", ".qt", ".rar", ".ras", ".raw", ".rgb", ".rip", ".rlc", ".rz", ".s3m", ".s7z", ".scpt", ".sgi", ".shar", ".sil",
+    ".smv", ".so", ".sub", ".swf", ".tar", ".tbz2", ".tga", ".tgz", ".tif", ".tiff", ".tlz", ".ts", ".ttf", ".uvh", ".uvi", ".uvm",
+    ".uvp", ".uvs", ".uvu", ".viv", ".vob", ".war", ".wav", ".wax", ".wbmp", ".wdp", ".weba", ".webm", ".webp", ".whl", ".wm", ".wma",
+    ".wmv", ".wmx", ".woff", ".woff2", ".wvx", ".xbm", ".xif", ".xm", ".xpi", ".xpm", ".xwd", ".xz", ".z", ".zip", ".zipx"
 ]
 
 PYPELINE_EXTENSIONS = utils.MARKDOWN_EXTENSIONS + ['.rst']
@@ -1478,6 +1478,10 @@ class Blob(object):
 
     @LazyProperty
     def has_html_view(self):
+        '''
+        Return true if file is a text file that can be displayed.
+        :return: boolean
+        '''
         if self.extension in BINARY_EXTENSIONS:
             return False
         if (self.content_type.startswith('text/') or

http://git-wip-us.apache.org/repos/asf/allura/blob/7133cb19/Allura/allura/tests/unit/test_repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_repo.py b/Allura/allura/tests/unit/test_repo.py
index 9008571..2e52ebe 100644
--- a/Allura/allura/tests/unit/test_repo.py
+++ b/Allura/allura/tests/unit/test_repo.py
@@ -153,13 +153,35 @@ class TestTree(unittest.TestCase):
 class TestBlob(unittest.TestCase):
 
     def test_pypeline_view(self):
-        blob = M.repository.Blob(Mock(), Mock(), Mock())
-        blob._id = 'blob1'
-        blob.path = Mock(return_value='path')
-        blob.name = 'INSTALL.mdown'
-        blob.extension = '.mdown'
+        blob = M.repository.Blob(Mock(), 'INSTALL.mdown', 'blob1')
         assert_equal(blob.has_pypeline_view, True)
 
+    def test_has_html_view_text_mime(self):
+        blob = M.repository.Blob(Mock(), 'INSTALL', 'blob1')
+        blob.content_type = 'text/plain'
+        assert_equal(blob.has_html_view, True)
+
+    def test_has_html_view_text_ext(self):
+        blob = M.repository.Blob(Mock(), 'INSTALL.txt', 'blob1')
+        blob.content_type = 'foo/bar'
+        assert_equal(blob.has_html_view, True)
+
+    def test_has_html_view_text_contents(self):
+        blob = M.repository.Blob(MagicMock(), 'INSTALL', 'blob1')
+        blob.content_type = 'foo/bar'
+        blob.text = 'hello world, this is text here'
+        assert_equal(blob.has_html_view, True)
+
+    def test_has_html_view_bin_ext(self):
+        blob = M.repository.Blob(Mock(), 'INSTALL.zip', 'blob1')
+        assert_equal(blob.has_html_view, False)
+
+    def test_has_html_view_bin_content(self):
+        blob = M.repository.Blob(MagicMock(), 'myfile', 'blob1')
+        blob.content_type = 'whatever'
+        blob.text = '\0\0\0\0'
+        assert_equal(blob.has_html_view, False)
+
 
 class TestCommit(unittest.TestCase):
 


[12/50] [abbrv] allura git commit: [#7897] ticket:828 Use SimpleMDE 1.4.0

Posted by he...@apache.org.
[#7897] ticket:828 Use SimpleMDE 1.4.0


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/49ef2414
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/49ef2414
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/49ef2414

Branch: refs/heads/hs/7925
Commit: 49ef2414ca8aca7e962d95583d9a6696ac589f39
Parents: 465f225
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Jul 27 16:25:54 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 16:25:54 2015 +0300

----------------------------------------------------------------------
 .../lib/widgets/resources/css/simplemde.min.css     |  4 ++--
 .../lib/widgets/resources/js/simplemde.min.js       | 16 ++++++++--------
 2 files changed, 10 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/49ef2414/Allura/allura/lib/widgets/resources/css/simplemde.min.css
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/css/simplemde.min.css b/Allura/allura/lib/widgets/resources/css/simplemde.min.css
index 8447ed7..a5de0d7 100644
--- a/Allura/allura/lib/widgets/resources/css/simplemde.min.css
+++ b/Allura/allura/lib/widgets/resources/css/simplemde.min.css
@@ -1,7 +1,7 @@
 /*!
- * SimpleMDE v1.2.1 (https://github.com/NextStepWebs/simplemde-markdown-editor)
+ * SimpleMDE v1.4.0 (https://github.com/NextStepWebs/simplemde-markdown-editor)
  * Copyright Next Step Webs, Inc.
  * Licensed under the MIT license
  */
 
-.CodeMirror{height:auto;min-height:300px;border:1px solid #ddd;border-bottom-left-radius:4px;border-bottom-right-radius:4px;padding:10px}:-webkit-full-screen{background:#f9f9f5;padding:.5em 1em;width:100%;height:100%}:-moz-full-screen{padding:.5em 1em;background:#f9f9f5;width:100%;height:100%}.editor-wrapper{font:16px/1.62 "Helvetica Neue","Xin Gothic","Hiragino Sans GB","WenQuanYi Micro Hei","Microsoft YaHei",sans-serif;color:#2c3e50}.editor-wrapper input.title{font:18px "Helvetica Neue","Xin Gothic","Hiragino Sans GB","WenQuanYi Micro Hei","Microsoft YaHei",sans-serif;background:0 0;padding:4px;width:100%;border:none;outline:0;opacity:.6}.editor-toolbar{position:relative;opacity:.6;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;padding:0 10px;border-top:1px solid #bbb;border-left:1px solid #bbb;border-right:1px solid #bbb;border-top-left-radius:4px;border-top-right-radius:4px}.editor-toolbar:after,.editor-toolbar:before{dis
 play:block;content:' ';height:1px}.editor-toolbar:before{margin-bottom:8px}.editor-toolbar:after{margin-top:8px}.editor-toolbar:hover,.editor-wrapper input.title:focus,.editor-wrapper input.title:hover{opacity:.8}.editor-toolbar a{display:inline-block;text-align:center;text-decoration:none!important;color:#2c3e50!important;width:30px;height:30px;margin:0;border:1px solid transparent;border-radius:3px;cursor:pointer}.editor-toolbar a.active,.editor-toolbar a:hover{background:#fcfcfc;border-color:#95a5a6}.editor-toolbar a:before{line-height:30px}.editor-toolbar i.separator{display:inline-block;width:0;border-left:1px solid #d9d9d9;border-right:1px solid #fff;color:transparent;text-indent:-10px;margin:0 6px}.editor-toolbar a.icon-fullscreen{position:absolute;right:10px}.editor-toolbar.disabled-for-preview a:not(.fa-eye){pointer-events:none;background:#fff;border:none}.editor-statusbar{padding:8px 10px;font-size:12px;color:#959694;text-align:right}.editor-statusbar span{display:inline-b
 lock;min-width:4em;margin-left:1em}.editor-statusbar .lines:before{content:'lines: '}.editor-statusbar .words:before{content:'words: '}.editor-preview{padding:10px;position:absolute;width:100%;height:100%;top:0;left:0;background:#fafafa;z-index:9999;overflow:auto;display:none}.editor-preview-active{display:block}.editor-preview>p{margin-top:0}.editor-preview pre{background:#eee;margin-bottom:10px}.editor-preview table td,table th{border:1px solid #ddd;padding:5px}.CodeMirror-scroll{overflow:auto}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror div.CodeMirror-cursor{border-left:1px solid #000;z-index:3}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7;z-index:1}.cm-s-paper .cm-keyword{color:#555}.cm-s-paper .cm-atom,.cm-s-paper .cm-number{color:#7f8c8d}.cm-s-paper .cm-def{color:#00f}.cm-s-paper .cm
 -variable{color:#000}.cm-s-paper .cm-variable-2{color:#555}.cm-s-paper .cm-variable-3{color:#085}.cm-s-paper .cm-operator,.cm-s-paper .cm-property{color:#000}.cm-s-paper .cm-comment{color:#959595}.cm-s-paper .cm-string{color:#7f8c8d}.cm-s-paper .cm-string-2{color:#f50}.cm-s-paper .cm-meta{color:#555}.cm-s-paper .cm-error{color:red}.cm-s-paper .cm-builtin,.cm-s-paper .cm-qualifier{color:#555}.cm-s-paper .cm-bracket{color:#997}.cm-s-paper .cm-attribute,.cm-s-paper .cm-tag{color:#7f8c8d}.cm-s-paper .cm-header{color:#000}.cm-s-paper .cm-quote{color:#888}.cm-s-paper .cm-hr{color:#999}.cm-s-paper .cm-link{color:#7f8c8d}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-invalidchar{color:red}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror{position:relative;overflow:hidden}.CodeMirror-scroll{margin-bottom:-30px;
 margin-right:-30px;padding-bottom:30px;padding-right:30px;height:100%;min-height:300px;outline:0;position:relative}.CodeMirror-sizer{position:relative}.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0;z-index:6}.CodeMirror-lines{cursor:text}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;-o-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-in
 dex:2;overflow:auto}.CodeMirror-widget{display:inline-block}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;visibility:hidden;border-right:none;width:0}.CodeMirror-focused div.CodeMirror-cursor{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#BDC3C7}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}@media print{.CodeMirror div.CodeMirror-cursor{visibility:hidden}}.CodeMirror .CodeMirror-code .cm-header-1{font-size:200%;line-height:200%}.CodeMirror .CodeMirror-code .cm-header-2{font-size:160%;line-height:160%}.CodeMirror .CodeMirror-code .cm-header-3{font-size:125%;line-height:125%}.CodeMirror .CodeMirror-code .cm-header-4{font-size:110%;line-height:110%}.CodeMirror .CodeMirror-code .cm-comment{background:#eee;border-radius:2
 px}
\ No newline at end of file
+.CodeMirror{height:auto;min-height:300px;border:1px solid #ddd;border-bottom-left-radius:4px;border-bottom-right-radius:4px;padding:10px}:-webkit-full-screen{background:#f9f9f5;padding:.5em 1em;width:100%;height:100%}:-moz-full-screen{padding:.5em 1em;background:#f9f9f5;width:100%;height:100%}.editor-wrapper{font:16px/1.62 "Helvetica Neue","Xin Gothic","Hiragino Sans GB","WenQuanYi Micro Hei","Microsoft YaHei",sans-serif;color:#2c3e50}.editor-wrapper input.title{font:18px "Helvetica Neue","Xin Gothic","Hiragino Sans GB","WenQuanYi Micro Hei","Microsoft YaHei",sans-serif;background:0 0;padding:4px;width:100%;border:none;outline:0;opacity:.6}.editor-toolbar{position:relative;opacity:.6;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;padding:0 10px;border-top:1px solid #bbb;border-left:1px solid #bbb;border-right:1px solid #bbb;border-top-left-radius:4px;border-top-right-radius:4px}.editor-toolbar:after,.editor-toolbar:before{dis
 play:block;content:' ';height:1px}.editor-toolbar:before{margin-bottom:8px}.editor-toolbar:after{margin-top:8px}.editor-toolbar:hover,.editor-wrapper input.title:focus,.editor-wrapper input.title:hover{opacity:.8}.editor-toolbar a{display:inline-block;text-align:center;text-decoration:none!important;color:#2c3e50!important;width:30px;height:30px;margin:0;border:1px solid transparent;border-radius:3px;cursor:pointer}.editor-toolbar a.active,.editor-toolbar a:hover{background:#fcfcfc;border-color:#95a5a6}.editor-toolbar a:before{line-height:30px}.editor-toolbar i.separator{display:inline-block;width:0;border-left:1px solid #d9d9d9;border-right:1px solid #fff;color:transparent;text-indent:-10px;margin:0 6px}.editor-toolbar a.icon-fullscreen{position:absolute;right:10px}.editor-toolbar.disabled-for-preview a:not(.fa-eye){pointer-events:none;background:#fff;border:none}.editor-statusbar{padding:8px 10px;font-size:12px;color:#959694;text-align:right}.editor-statusbar span{display:inline-b
 lock;min-width:4em;margin-left:1em}.editor-statusbar .lines:before{content:'lines: '}.editor-statusbar .words:before{content:'words: '}.editor-preview{padding:10px;position:absolute;width:100%;height:100%;top:0;left:0;background:#fafafa;z-index:9999;overflow:auto;display:none}.CodeMirror,.CodeMirror-sizer{position:relative}.editor-preview-active{display:block}.editor-preview>p{margin-top:0}.editor-preview pre{background:#eee;margin-bottom:10px}.editor-preview table td,table th{border:1px solid #ddd;padding:5px}.CodeMirror-scroll{overflow:auto}.CodeMirror-lines{padding:4px 0;cursor:text}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror div.CodeMirror-cursor{border-left:1px solid #000;z-index:3}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7;z-index:1}.cm-s-paper .cm-keyword{color:#555}.cm-s-paper .cm-atom,.cm-s-paper .cm-number{
 color:#7f8c8d}.cm-s-paper .cm-def{color:#00f}.cm-s-paper .cm-variable{color:#000}.cm-s-paper .cm-variable-2{color:#555}.cm-s-paper .cm-variable-3{color:#085}.cm-s-paper .cm-operator,.cm-s-paper .cm-property{color:#000}.cm-s-paper .cm-comment{color:#959595}.cm-s-paper .cm-string{color:#7f8c8d}.cm-s-paper .cm-string-2{color:#f50}.cm-s-paper .cm-meta{color:#555}.cm-s-paper .cm-error{color:red}.cm-s-paper .cm-builtin,.cm-s-paper .cm-qualifier{color:#555}.cm-s-paper .cm-bracket{color:#997}.cm-s-paper .cm-attribute,.cm-s-paper .cm-tag{color:#7f8c8d}.cm-s-paper .cm-header{color:#000}.cm-s-paper .cm-quote{color:#888}.cm-s-paper .cm-hr{color:#999}.cm-s-paper .cm-link{color:#7f8c8d}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-invalidchar{color:red}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror{overflow:hidd
 en}.CodeMirror-scroll{margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;padding-right:30px;height:100%;min-height:300px;outline:0;position:relative}.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0;z-index:6}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;-o-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.Cod
 eMirror-widget{display:inline-block}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;visibility:hidden;border-right:none;width:0}.CodeMirror-focused div.CodeMirror-cursor{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#BDC3C7}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}@media print{.CodeMirror div.CodeMirror-cursor{visibility:hidden}}.CodeMirror .CodeMirror-code .cm-header-1{font-size:200%;line-height:200%}.CodeMirror .CodeMirror-code .cm-header-2{font-size:160%;line-height:160%}.CodeMirror .CodeMirror-code .cm-header-3{font-size:125%;line-height:125%}.CodeMirror .CodeMirror-code .cm-header-4{font-size:110%;line-height:110%}.CodeMirror .CodeMirror-code .cm-comment{background:rgba(0,0,0,.05);border-radius:2px}.CodeMirro
 r .CodeMirror-code .cm-strikethrough{text-decoration:line-through}.CodeMirror .cm-spell-error:not(.cm-url){background:rgba(255,0,0,.15)}
\ No newline at end of file


[41/50] [abbrv] allura git commit: [#7925] show diffs of renames & copies (if they had changes)

Posted by he...@apache.org.
[#7925] show diffs of renames & copies (if they had changes)


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b950a1fd
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b950a1fd
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b950a1fd

Branch: refs/heads/hs/7925
Commit: b950a1fd6eeff1e3c7e0d7dc58b3387af70f70d3
Parents: 95f5648
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 22:32:35 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:37 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py          | 17 ++++++++++++-----
 Allura/allura/templates/repo/commit.html         | 12 +++++++++++-
 ForgeGit/forgegit/model/git_repo.py              |  1 -
 ForgeSVN/forgesvn/model/svn.py                   |  1 -
 ForgeSVN/forgesvn/tests/model/test_repository.py |  4 ++--
 5 files changed, 25 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b950a1fd/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index c17f06a..699931b 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -724,11 +724,11 @@ class FileBrowser(BaseController):
         elif 'diff' in kw:
             tg.decorators.override_template(
                 self.index, 'jinja:allura:templates/repo/diff.html')
-            return self.diff(kw['diff'], kw.pop('diformat', None))
+            return self.diff(kw['diff'], kw.pop('diformat', None), kw.pop('prev_file', None))
         elif 'barediff' in kw:
             tg.decorators.override_template(
                 self.index, 'jinja:allura:templates/repo/barediff.html')
-            return self.diff(kw['barediff'], kw.pop('diformat', None))
+            return self.diff(kw['barediff'], kw.pop('diformat', None), kw.pop('prev_file', None))
         else:
             force_display = 'force' in kw
             stats = utils.generate_code_stats(self._blob)
@@ -753,13 +753,20 @@ class FileBrowser(BaseController):
             'attachment;filename="%s"' % filename)
         return iter(self._blob)
 
-    def diff(self, commit, fmt=None, **kw):
+    def diff(self, prev_commit, fmt=None, prev_file=None, **kw):
+        '''
+        :param prev_commit: previous commit to compare against
+        :param fmt: "sidebyside", or anything else for "unified"
+        :param prev_file: previous filename, if different
+        :return:
+        '''
         try:
             path, filename = os.path.split(self._blob.path())
-            a_ci = c.app.repo.commit(commit)
-            a = a_ci.get_path(self._blob.path())
+            a_ci = c.app.repo.commit(prev_commit)
+            a = a_ci.get_path(prev_file or self._blob.path())
             apath = a.path()
         except:
+            # prev commit doesn't have the file
             a = []
             apath = ''
         b = self._blob

http://git-wip-us.apache.org/repos/asf/allura/blob/b950a1fd/Allura/allura/templates/repo/commit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/commit.html b/Allura/allura/templates/repo/commit.html
index b0adabc..06da620 100644
--- a/Allura/allura/templates/repo/commit.html
+++ b/Allura/allura/templates/repo/commit.html
@@ -148,6 +148,10 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                 <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file.old))}}">{{h.really_unicode(file.old)}}</a>
                 to
                 <a href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file.new))}}">{{h.really_unicode(file.new)}}</a>
+                {% if file.ratio != 1 %}
+                    <a class="commit-diff-link" href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file['new']))}}?diff={{prev[0]._id if prev else ''}}&prev_file={{h.urlquote(h.really_unicode(file['old']))}}">Diff</a>
+                    <a class="commit-diff-link switch-diff-format-link" data-diformat="{{session.diformat}}" data-diffid="diff-{{loop.index}}" href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file['new']))}}?barediff={{prev[0]._id if prev else ''}}&prev_file={{h.urlquote(h.really_unicode(file['old']))}}">Switch to {{'unified' if session.diformat == 'sidebyside' else 'side-by-side'}} view</a>
+                {% endif %}
             {% endif %}
             </h6>
             <div id="diff-{{loop.index}}" class="inline-diff-body">
@@ -157,7 +161,13 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                   {% if file.ratio == 1 %}
                     <span class="empty-diff">File was {{ type }}.</span>
                   {% else %}
-                    {{g.highlight(file.diff, lexer='diff')}}
+                    <img src="{{g.forge_static('images/spinner.gif')}}" class="loading_icon" alt="Loading..."/>
+                    <script type="text/javascript">
+                      diff_queue.push({
+                        selector: '#diff-{{loop.index}}',
+                        url: '{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file['new']))}}?barediff={{prev[0]._id if prev else ''}}&prev_file={{h.urlquote(h.really_unicode(file['old']))}}'
+                      });
+                    </script>
                   {% endif %}
                 {% elif obj_type == 'tree' %}
                     <span class="empty-diff">Directory.</span>

http://git-wip-us.apache.org/repos/asf/allura/blob/b950a1fd/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 9462087..8849a40 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -681,7 +681,6 @@ class GitImplementation(M.RepositoryImplementation):
                     'new': h.really_unicode(cmd_output[x + 2]),
                     'old': h.really_unicode(cmd_output[x + 1]),
                     'ratio': ratio,
-                    'diff': '',
                 }))
                 x += 3
             else:

http://git-wip-us.apache.org/repos/asf/allura/blob/b950a1fd/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index b9d986e..8db0943 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -803,7 +803,6 @@ class SVNImplementation(M.RepositoryImplementation):
                     'new': h.really_unicode(p.path),
                     'old': h.really_unicode(p.copyfrom_path),
                     'ratio': 1,
-                    'diff': '',
                 })
             elif p['action'] == 'A':
                 result['added'].append(h.really_unicode(p.path))

http://git-wip-us.apache.org/repos/asf/allura/blob/b950a1fd/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 1c997b7..f5ce1df 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -407,7 +407,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
     def test_diff_copy(self):
         entry = self.repo.commit(self.repo.log(5, id_only=True).next())
         assert_equals(dict(entry.diffs), dict(
-                copied=[{'new': u'/b', 'old': u'/a', 'diff': '', 'ratio': 1}],  renamed=[],
+                copied=[{'new': u'/b', 'old': u'/a', 'ratio': 1}],  renamed=[],
                 changed=[], removed=[], added=[], total=1))
 
     def test_commit(self):
@@ -612,7 +612,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
                 'removed': [],
                 'modified': [],
                 'copied': [
-                    {'new': u'/b', 'old': u'/a', 'diff': '', 'ratio': 1},
+                    {'new': u'/b', 'old': u'/a', 'ratio': 1},
                 ],
                 'renamed': [],
             }],


[04/50] [abbrv] allura git commit: [#7897] ticket:823 Make editor more compact by default

Posted by he...@apache.org.
[#7897] ticket:823 Make editor more compact by default


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/c9b39c93
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/c9b39c93
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/c9b39c93

Branch: refs/heads/hs/7925
Commit: c9b39c93a26de58f9e2ddfa999e02574fa43df44
Parents: eaba477
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 17 17:21:56 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/css/markitup_sf.css | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c9b39c93/Allura/allura/lib/widgets/resources/css/markitup_sf.css
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/css/markitup_sf.css b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
index 5dd88cd..9712461 100644
--- a/Allura/allura/lib/widgets/resources/css/markitup_sf.css
+++ b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
@@ -23,13 +23,13 @@
   margin-bottom: 5px;
 }
 .markdown_edit .CodeMirror {
-  min-height: 120px;
+  min-height: 60px;
   border-bottom: none;
   border-bottom-left-radius: 0;
   border-bottom-right-radius: 0;
 }
 .markdown_edit .CodeMirror-scroll {
-  min-height: 120px;
+  min-height: 60px;
 }
 .markdown_edit .editor-statusbar {
   border: 1px solid #ddd;


[03/50] [abbrv] allura git commit: [#7897] ticket:820 Clean up styles for SimpleMDE

Posted by he...@apache.org.
[#7897] ticket:820 Clean up styles for SimpleMDE


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d78d322c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d78d322c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d78d322c

Branch: refs/heads/hs/7925
Commit: d78d322c698802c3916dd52e5cda957d0ead7542
Parents: cb55aa8
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Jul 14 13:58:22 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/lib/widgets/discuss.py            |  4 +-
 .../lib/widgets/resources/css/markitup_sf.css   | 38 +++--------
 .../lib/widgets/resources/js/sf_markitup.js     | 67 ++++++++++----------
 Allura/allura/nf/allura/css/site_style.css      |  2 +-
 .../forgewiki/templates/wiki/page_edit.html     |  8 +--
 5 files changed, 46 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d78d322c/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index db9342c..ff131e8 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -157,9 +157,7 @@ class EditPost(ff.ForgeForm):
     @property
     def fields(self):
         fields = ew_core.NameList()
-        fields.append(ffw.MarkdownEdit(
-            name='text',
-            attrs={'style': 'height:7em; width:97%'}))
+        fields.append(ffw.MarkdownEdit(name='text'))
         fields.append(ew.HiddenField(name='forum', if_missing=None))
         if ew_core.widget_context.widget:
             # we are being displayed

http://git-wip-us.apache.org/repos/asf/allura/blob/d78d322c/Allura/allura/lib/widgets/resources/css/markitup_sf.css
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/css/markitup_sf.css b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
index 5e85697..5837469 100644
--- a/Allura/allura/lib/widgets/resources/css/markitup_sf.css
+++ b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
@@ -17,43 +17,23 @@
        under the License.
 */
 .markdown_edit {
-  height: 200px;
-  min-height: 200px;
   width: 95%;
-  font-family: Consolas, "Andale Mono", "Lucida Console", monospace;
-
-  -moz-border-radius: 4px;
-  -webkit-border-radius: 4px;
-  -o-border-radius: 4px;
-  -ms-border-radius: 4px;
-  -khtml-border-radius: 4px;
-  border-radius: 4px;
-  -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) inset,0 1px 0 rgba(255, 255, 255, 0.9);
-  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) inset,0 1px 0 rgba(255, 255, 255, 0.9);
-  -o-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) inset,0 1px 0 rgba(255, 255, 255, 0.9);
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) inset,0 1px 0 rgba(255, 255, 255, 0.9);
-  border: medium none;
-  margin-bottom: 5px;
-  margin-left: 2px;
-  border: 1px solid #aaaaaa;
   background: white;
 }
-
 .markdown_edit .CodeMirror {
-  height: auto;
   min-height: 120px;
+  border-bottom: none;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
 }
-
-.markdown_edit .editor-toolbar:before {
-  background: none;  /* hide toolbar's top border */
+.markdown_edit .CodeMirror-scroll {
+  min-height: 120px;
 }
-
-.markdown_edit .CodeMirror-sizer,
-.markdown_edit .editor-preview {
-  padding: 5px;
+.markdown_edit .editor-statusbar {
+  border: 1px solid #ddd;
+  border-bottom-left-radius: 4px;
+  border-bottom-right-radius: 4px;
 }
-
-
 .markdown_edit .editor-preview {
   z-index: 1001;  /* should always be under help modal */
 }

http://git-wip-us.apache.org/repos/asf/allura/blob/d78d322c/Allura/allura/lib/widgets/resources/js/sf_markitup.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/sf_markitup.js b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
index 91d63ca..b05f698 100644
--- a/Allura/allura/lib/widgets/resources/js/sf_markitup.js
+++ b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
@@ -27,46 +27,36 @@ $(window).load(function() {
             var $help_area = $('div.markdown_help', $container);
             var $help_contents = $('div.markdown_help_contents', $container);
 
+            // Add "info" tool & override action "preview" tool
             var toolbar = [];
-            // Exclude "code" tool from toolbar, since it's syntax not matching Allura's
-            // Override actions for "info" & "preview" tools
-            for (var i in Editor.toolbar) {
-              var tool = Editor.toolbar[i];
-              if (tool !== null && typeof tool === 'object') {
-                switch(tool.name) {
-                  case 'code':
-                    continue;
-                  case 'info':
-                    tool = {name: 'info', action: show_help};
-                    break;
-                  case 'preview':
-                    tool = {name: 'preview', action: show_preview};
-                    break;
-                }
+            for (var i in SimpleMDE.toolbar) {
+              var tool = SimpleMDE.toolbar[i];
+              if (tool !== null && typeof tool === 'object' && tool.name === 'preview') {
+                  toolbar.push({
+                    name: 'info',
+                    action: show_help,
+                    className: 'fa fa-info'
+                  });
+                  toolbar.push({
+                    name: 'preview',
+                    action: show_preview,
+                    className: 'fa fa-eye'
+                  });
+              } else {
+                toolbar.push(tool);
               }
-              toolbar.push(tool);
             }
-            var editor = new Editor({
+
+            var editor = new SimpleMDE({
               element: $textarea[0],
+              autofocus: false,
               toolbar: toolbar
             });
-            var cm = editor.codemirror;
-            cm.on('viewportChange', resize);
             editor.render();
-            // trigger resize to properly display editor in case of a lot of text in the textarea
-            resize(cm);
 
             // focus editor by clicking anywhere on it, not only on the first few lines
             $('.CodeMirror').click(function () { this.CodeMirror.focus(); });
 
-            function resize(cm) {
-              var toolbar_h = $('.editor-toolbar', $container).outerHeight();
-              var statusbar_h = $('.editor-statusbar', $container).outerHeight();
-              var cm_h = cm.getScrollInfo().clientHeight;
-              var h = toolbar_h + statusbar_h + cm_h;
-              $container.height(h);
-            }
-
             function show_help(editor) {
               $help_contents.html('Loading...');
               $.get($help_contents.attr('data-url'), function (data) {
@@ -89,11 +79,13 @@ $(window).load(function() {
 
             function show_preview(editor) {
               /*
-               * This is pretty much the same as original Editor.togglePreview,
+               * This is pretty much the same as original SimpleMDE.togglePreview,
                * but rendered text is fetched from the server.
-               * https://github.com/lepture/editor/blob/0f493bfdc7c3014ee7ac656f41b5b52f8955b2e9/src/intro.js#L216-L242
+               * https://github.com/NextStepWebs/simplemde-markdown-editor/blob/1.2.1/source%20files/markdownify.js#L218-L249
                */
+              var toolbar_div = document.getElementsByClassName('editor-toolbar')[0];
               var toolbar = editor.toolbar.preview;
+              var parse = editor.constructor.markdown;
               var cm = editor.codemirror;
               var wrapper = cm.getWrapperElement();
               var preview = wrapper.lastChild;
@@ -104,18 +96,23 @@ $(window).load(function() {
               }
               if (/editor-preview-active/.test(preview.className)) {
                 preview.className = preview.className.replace(
-                    /\s*editor-preview-active\s*/g, ''
-                    );
+                  /\s*editor-preview-active\s*/g, ''
+                );
                 toolbar.className = toolbar.className.replace(/\s*active\s*/g, '');
+                toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview\s*/g, '');
               } else {
                 /* When the preview button is clicked for the first time,
                  * give some time for the transition from editor.css to fire and the view to slide from right to left,
                  * instead of just appearing.
                  */
-                setTimeout(function() {preview.className += ' editor-preview-active';}, 1);
+                setTimeout(function() {
+                  preview.className += ' editor-preview-active';
+                }, 1);
                 toolbar.className += ' active';
+                toolbar_div.className += ' disabled-for-preview';
               }
-              get_rendered_text(preview, cm.getValue());
+              var text = cm.getValue();
+              get_rendered_text(preview, text);
             }
 
             function get_rendered_text(preview, text) {

http://git-wip-us.apache.org/repos/asf/allura/blob/d78d322c/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index df0b932..80081e4 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -2657,7 +2657,7 @@ div.attachment_thumb .file_type span {
   border-left: 1px solid #d7d7d7;
   position: absolute;
   top: 50px;
-  left: 86px;
+  left: 85px;
 }
 
 .edit_post_form.reply .arw {

http://git-wip-us.apache.org/repos/asf/allura/blob/d78d322c/ForgeWiki/forgewiki/templates/wiki/page_edit.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_edit.html b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
index c9596b7..2bcb94b 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_edit.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
@@ -25,13 +25,9 @@
 
 {% block extra_css %}
 <style type="text/css">
-  .markdown_edit {
-    height: 600px;
-    min-height: 600px;
-  }
   .markdown_edit .CodeMirror {
     height: auto;
-    min-height: 520px;
+    min-height: 600px;
   }
 </style>
 {% endblock %}
@@ -68,10 +64,12 @@
 	  {{c.markdown_editor.display(id='text', name='text',value=page.text)}}
 	</div>
 	<div style="clear:both;"></div>
+  <div style="margin-top: 1em;">
 	<label class="grid-4">Labels:</label>
 	<div class="grid-14" style="margin-left:0">
 		{{c.label_edit.display(id='labels', name='labels', value=page.labels)}}
 	</div>
+  </div>
   <div class="grid-19">
     <input type="submit" value="Save">
     <input type="reset" value="Cancel">


[19/50] [abbrv] allura git commit: [#7947] don't allow any cached markdown from before this fix to be used

Posted by he...@apache.org.
[#7947] don't allow any cached markdown from before this fix to be used


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/ad029f87
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/ad029f87
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/ad029f87

Branch: refs/heads/hs/7925
Commit: ad029f8752e8529fd7c5fe0928592ab8ed4f8c3a
Parents: dd3ca5b
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Aug 3 18:49:21 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Aug 3 18:55:27 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/ad029f87/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 2a7ee5c..5d262e8 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -103,11 +103,12 @@ class ForgeMarkdown(markdown.Markdown):
                 field_name, artifact.__class__.__name__)
             return self.convert(source_text)
 
+        bugfix_rev = 2  # increment this if we need all caches to invalidated (e.g. xss in markdown rendering fixed)
         md5 = None
         # If a cached version exists and it is valid, return it.
         if cache.md5 is not None:
             md5 = hashlib.md5(source_text.encode('utf-8')).hexdigest()
-            if cache.md5 == md5 and getattr(cache, 'fix7528', False):
+            if cache.md5 == md5 and getattr(cache, 'fix7528', False) == bugfix_rev:
                 return h.html.literal(cache.html)
 
         # Convert the markdown and time the result.
@@ -128,7 +129,7 @@ class ForgeMarkdown(markdown.Markdown):
             if md5 is None:
                 md5 = hashlib.md5(source_text.encode('utf-8')).hexdigest()
             cache.md5, cache.html, cache.render_time = md5, html, render_time
-            cache.fix7528 = True  # flag to indicate good caches created after [#7528] was fixed
+            cache.fix7528 = bugfix_rev  # flag to indicate good caches created after [#7528] and other critical bugs were fixed.
 
             # Prevent cache creation from updating the mod_date timestamp.
             _session = artifact_orm_session._get()


[06/50] [abbrv] allura git commit: [#7897] ticket:823 Insert 4 spaces instead of a tab

Posted by he...@apache.org.
[#7897] ticket:823 Insert 4 spaces instead of a tab


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/cb8e49ff
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/cb8e49ff
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/cb8e49ff

Branch: refs/heads/hs/7925
Commit: cb8e49ffcd23586c02995ae5753ed3d8e2cd5c1d
Parents: 9ff9337
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 17 16:54:48 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/js/sf_markitup.js | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/cb8e49ff/Allura/allura/lib/widgets/resources/js/sf_markitup.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/sf_markitup.js b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
index 47cc6a7..6570d6a 100644
--- a/Allura/allura/lib/widgets/resources/js/sf_markitup.js
+++ b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
@@ -50,6 +50,8 @@ $(window).load(function() {
             var editor = new SimpleMDE({
               element: $textarea[0],
               autofocus: false,
+              indentWithTabs: false,
+              tabSize: 4,
               toolbar: toolbar
             });
             editor.render();


[13/50] [abbrv] allura git commit: [#7897] ticket:828 Update editor initialization for new version

Posted by he...@apache.org.
[#7897] ticket:828 Update editor initialization for new version


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b89befe5
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b89befe5
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b89befe5

Branch: refs/heads/hs/7925
Commit: b89befe55c454aa496d9fc4bd3b9d855205ed541
Parents: 49ef241
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Jul 27 16:38:35 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 16:38:35 2015 +0300

----------------------------------------------------------------------
 .../lib/widgets/resources/js/sf_markitup.js     | 44 +++++++++++++-------
 1 file changed, 30 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b89befe5/Allura/allura/lib/widgets/resources/js/sf_markitup.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/sf_markitup.js b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
index 6570d6a..4ca7e5d 100644
--- a/Allura/allura/lib/widgets/resources/js/sf_markitup.js
+++ b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
@@ -27,29 +27,45 @@ $(window).load(function() {
             var $help_area = $('div.markdown_help', $container);
             var $help_contents = $('div.markdown_help_contents', $container);
 
-            // Add "info" tool & override action "preview" tool
+            // Override action for "preview" & "guide" tools
             var toolbar = [];
             for (var i in SimpleMDE.toolbar) {
               var tool = SimpleMDE.toolbar[i];
-              if (tool !== null && typeof tool === 'object' && tool.name === 'preview') {
-                  toolbar.push({
-                    name: 'info',
-                    action: show_help,
-                    className: 'fa fa-info'
-                  });
-                  toolbar.push({
-                    name: 'preview',
-                    action: show_preview,
-                    className: 'fa fa-eye'
-                  });
-              } else {
-                toolbar.push(tool);
+              if (tool !== null && typeof tool === 'object') {
+                switch (tool.name) {
+                  case 'guide':
+                    tool = {
+                      name: tool.name,
+                      action: show_help,
+                      className: tool.className
+                    };
+                    break;
+                  case 'preview':
+                    tool = {
+                      name: tool.name,
+                      action: show_preview,
+                      className: tool.className
+                    };
+                    break;
+                }
               }
+              toolbar.push(tool);
             }
 
             var editor = new SimpleMDE({
               element: $textarea[0],
               autofocus: false,
+              /*
+               * spellChecker: false is important!
+               * It's enabled by default and consumes a lot of memory and CPU
+               * if you have more than one editor on the page. In Allura we
+               * usually have a lot of (hidden) editors on the page (e.g.
+               * comments). On my machine it consumes ~1G of memory for a page
+               * with ~10 comments.
+               * We're using bleeding age 1.4.0, we might want to
+               * re-check when more stable version will be available.
+               */
+              spellChecker: false,
               indentWithTabs: false,
               tabSize: 4,
               toolbar: toolbar


[35/50] [abbrv] allura git commit: [#7925] Improve binary file detection

Posted by he...@apache.org.
[#7925] Improve binary file detection


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/7eeb0dd0
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/7eeb0dd0
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/7eeb0dd0

Branch: refs/heads/hs/7925
Commit: 7eeb0dd06ec8f0aca4a890efe0fae4c9524c4972
Parents: e252f5e
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Mon Jul 27 15:58:59 2015 -0400
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:35 2015 -0400

----------------------------------------------------------------------
 Allura/allura/model/repository.py | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/7eeb0dd0/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 7bc36c1..5fe2ba9 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -77,11 +77,21 @@ SObjType = S.OneOf('blob', 'tree', 'submodule')
 
 # Used for when we're going to batch queries using $in
 QSIZE = 100
-README_RE = re.compile('^README(\.[^.]*)?$', re.IGNORECASE)
-VIEWABLE_EXTENSIONS = [
-    '.php', '.py', '.js', '.java', '.html', '.htm', '.yaml', '.sh',
-    '.rb', '.phtml', '.txt', '.bat', '.ps1', '.xhtml', '.css', '.cfm', '.jsp', '.jspx',
-    '.pl', '.php4', '.php3', '.rhtml', '.svg', '.markdown', '.json', '.ini', '.tcl', '.vbs', '.xsl']
+BINARY_EXTENSIONS = [
+    "3ds", "3g2", "3gp", "7z", "a", "aac", "adp", "ai", "aif", "apk", "ar", "asf", "au", "avi",
+    "bak", "bin", "bk", "bmp", "btif", "bz2", "cab", "caf", "cgm", "cmx", "cpio", "cr2", "dat", "deb", "djvu", "dll",
+    "dmg", "dng", "doc", "docx", "dra", "DS_Store", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ecelp4800",
+    "ecelp7470", "ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "fli", "flv",
+    "fpx", "fst", "fvt", "g3", "gif", "gz", "h261", "h263", "h264", "ico", "ief", "img", "ipa", "iso", "jar", "jpeg",
+    "jpg", "jpgv", "jpm", "jxr", "ktx", "lvp", "lz", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mid", "mj2",
+    "mka", "mkv", "mmr", "mng", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "mxu", "nef", "npx", "o",
+    "oga", "ogg", "ogv", "otf", "pbm", "pcx", "pdf", "pea", "pgm", "pic", "png", "pnm", "ppm", "psd", "pya", "pyc",
+    "pyo", "pyv", "qt", "rar", "ras", "raw", "rgb", "rip", "rlc", "rz", "s3m", "s7z", "scpt", "sgi", "shar", "sil",
+    "smv", "so", "sub", "swf", "tar", "tbz2", "tga", "tgz", "tif", "tiff", "tlz", "ts", "ttf", "uvh", "uvi", "uvm",
+    "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wm", "wma",
+    "wmv", "wmx", "woff", "woff2", "wvx", "xbm", "xif", "xm", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx"
+]
+
 PYPELINE_EXTENSIONS = utils.MARKDOWN_EXTENSIONS + ['.rst']
 
 DIFF_SIMILARITY_THRESHOLD = .5  # used for determining file renames
@@ -1520,12 +1530,6 @@ class Blob(object):
         return self._content_type_encoding[0]
 
     @LazyProperty
-    def is_text(self):
-        """Return true if this blob is text."""
-
-        return self.content_type.startswith("text")
-
-    @LazyProperty
     def content_encoding(self):
         return self._content_type_encoding[1]
 
@@ -1535,8 +1539,10 @@ class Blob(object):
             return True
         return False
 
-    @property
+    @LazyProperty
     def has_html_view(self):
+        if self.extension in BINARY_EXTENSIONS:
+            return False
         if (self.content_type.startswith('text/') or
                 self.extension in VIEWABLE_EXTENSIONS or
                 self.extension in PYPELINE_EXTENSIONS or


[26/50] [abbrv] allura git commit: [#7915] more exact links into installation docs

Posted by he...@apache.org.
[#7915] more exact links into installation docs


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/acd5b126
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/acd5b126
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/acd5b126

Branch: refs/heads/hs/7925
Commit: acd5b1268f24895a90d9493b1230852bcc4db1e3
Parents: 9187071
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Aug 5 17:50:37 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Aug 5 17:53:24 2015 -0400

----------------------------------------------------------------------
 INSTALL.markdown | 2 +-
 README.markdown  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/acd5b126/INSTALL.markdown
----------------------------------------------------------------------
diff --git a/INSTALL.markdown b/INSTALL.markdown
index 57c0b89..b9a74b9 100644
--- a/INSTALL.markdown
+++ b/INSTALL.markdown
@@ -17,4 +17,4 @@
     under the License.
 -->
 
-See `Allura/docs`.
+See see `Allura/docs/getting_started/installation.rst` or <https://forge-allura.apache.org/docs/getting_started/installation.html>.

http://git-wip-us.apache.org/repos/asf/allura/blob/acd5b126/README.markdown
----------------------------------------------------------------------
diff --git a/README.markdown b/README.markdown
index 5eec88f..1e762da 100644
--- a/README.markdown
+++ b/README.markdown
@@ -22,7 +22,7 @@ Apache Allura
 
 Allura is an open source implementation of a software "forge", a web site that manages source code repositories, bug reports, discussions, mailing lists, wiki pages, blogs and more for any number of individual projects.
 
-To install Allura, see `Allura/docs`.
+To install Allura, see `Allura/docs/getting_started/installation.rst` or <https://forge-allura.apache.org/docs/getting_started/installation.html>.
 
 Website: <https://allura.apache.org/>
 


[25/50] [abbrv] allura git commit: [#7915] remove an unnecessary heading level; avoid error about virtualbox links having same name (__ instead of _ makes it an anonymous link)

Posted by he...@apache.org.
[#7915] remove an unnecessary heading level; avoid error about virtualbox links having same name (__ instead of _ makes it an anonymous link)


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/ff2fff44
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/ff2fff44
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/ff2fff44

Branch: refs/heads/hs/7925
Commit: ff2fff44e5bc8567b3440bc7ec5dbd9de0a5ee63
Parents: a8ace0d
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Aug 5 17:29:10 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Aug 5 17:53:23 2015 -0400

----------------------------------------------------------------------
 Allura/docs/getting_started/installation.rst | 28 +++++++++++------------
 1 file changed, 14 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/ff2fff44/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index 90fbeee..d43d52d 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -29,9 +29,9 @@ Step-by-Step Installation
 
 For a simpler setup using Docker images, see :ref:`docker-install` instead.
 
-In these instructions, we'll use `VirtualBox <http://www.virtualbox.org>`_ and `Ubuntu 14.04 <http://ubuntu.com>`_ (12.04 works too) to create a disposable sandbox for Allura development/testing.  Allura should work on other Linux systems (including OSX), but setting up all the dependencies will be different.
+In these instructions, we'll use `VirtualBox <http://www.virtualbox.org>`__ and `Ubuntu 14.04 <http://ubuntu.com>`_ (12.04 works too) to create a disposable sandbox for Allura development/testing.  Allura should work on other Linux systems (including OSX), but setting up all the dependencies will be different.
 
-* Download and install `VirtualBox <http://www.virtualbox.org/wiki/Downloads>`_ for your platform.
+* Download and install `VirtualBox <http://www.virtualbox.org/wiki/Downloads>`__ for your platform.
 
 * Download a minimal `Ubuntu 14.04 64-bit ISO <https://help.ubuntu.com/community/Installation/MinimalCD>`_.
 
@@ -44,8 +44,8 @@ In these instructions, we'll use `VirtualBox <http://www.virtualbox.org>`_ and `
 * Consult `available documentation <https://help.ubuntu.com/>`_ for help installing Ubuntu.
 
 
-Installation
-^^^^^^^^^^^^
+System Packages
+^^^^^^^^^^^^^^^
 
 Before we begin, you'll need to install some system packages.
 
@@ -62,7 +62,7 @@ Optional, for SVN support:
     ~$ sudo aptitude install subversion python-svn
 
 Setting up a virtual python environment
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The first step to installing the Allura platform is installing a virtual environment via `virtualenv <https://virtualenv.pypa.io/en/latest/>`_.  This helps keep our distribution python installation clean.
 
@@ -87,7 +87,7 @@ In order to use the virtual environment, you'll need to activate it:
 You'll need to do this whenever you're working on the Allura codebase so you may want to consider adding it to your :file:`~/.bashrc` file.
 
 Creating the log directory
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 .. code-block:: bash
 
@@ -95,7 +95,7 @@ Creating the log directory
     (env-allura)~$ sudo chown $(whoami) /var/log/allura
 
 Installing the Allura code and dependencies
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Now we can get down to actually getting the Allura code and dependencies downloaded and ready to go.  If you don't have the source code yet, run:
 
@@ -133,12 +133,12 @@ Next, run :code:`./rebuild-all.bash` to setup all the Allura applications.  If y
     # repeat for any other tools you want to use
 
 Initializing the environment
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The Allura forge consists of several components, all of which need to be running to have full functionality.
 
 SOLR search and indexing server
-*******************************
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 We have a custom config ready for use.
 
@@ -154,7 +154,7 @@ We have a custom config ready for use.
 
 
 Create code repo directories
-****************************
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The default configuration stores repos in :file:`/srv`, so we need to create those directories:
 
@@ -169,7 +169,7 @@ If you don't have :code:`sudo` permission or just want to store them somewhere e
 If you want to set up remote access to the repositories, see :ref:`scm_hosting`
 
 Allura task processing
-**********************
+~~~~~~~~~~~~~~~~~~~~~~
 
 Allura uses a background task service called "taskd" to do async tasks like sending emails, and indexing data into solr, etc.  Let's get it running
 
@@ -179,7 +179,7 @@ Allura uses a background task service called "taskd" to do async tasks like send
     (env-allura)~/src/allura/Allura$ nohup paster taskd development.ini > /var/log/allura/taskd.log 2>&1 &
 
 The application server
-**********************
+~~~~~~~~~~~~~~~~~~~~~~
 
 In order to initialize the Allura database, you'll need to run the following:
 
@@ -202,7 +202,7 @@ This shouldn't take too long, but it will start the taskd server doing tons of s
     (env-allura)~/src/allura/Allura$ nohup paster serve --reload development.ini  > /var/log/allura/allura.log 2>&1 &
 
 Next Steps
-~~~~~~~~~~
+^^^^^^^^^^
 
 Go to the Allura webapp running on your `local machine <http://localhost:8080/>`_ port 8080.
 (If you're running this inside a VM, you'll probably have to configure the port forwarding settings)
@@ -214,7 +214,7 @@ There are a few default projects (like "test") and neighborhoods.  Feel free to
 register a new project in your own forge, visit `/p/add_project`.
 
 Extra
-~~~~~
+^^^^^
 
 * Read :ref:`post-setup-instructions`
 * Ask questions and discuss Allura on the `allura-dev mailing list <http://mail-archives.apache.org/mod_mbox/allura-dev/>`_


[28/50] [abbrv] allura git commit: Remove unused #help CSS (has been around forever, never used) which will alleviate one case of #7945 css interference

Posted by he...@apache.org.
Remove unused #help CSS (has been around forever, never used) which will alleviate one case of #7945 css interference


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/dc857c58
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/dc857c58
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/dc857c58

Branch: refs/heads/hs/7925
Commit: dc857c58f597564667fea437a03a51ed1e1def4a
Parents: d07cd70
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Aug 5 17:53:31 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Aug 6 13:18:41 2015 +0300

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css | 13 -------------
 1 file changed, 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dc857c58/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 055583e..5a6339c 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -803,19 +803,6 @@ blockquote {
   border: 1px solid black;
 }
 
-/* help */
-#help {
-  width: 100%;
-  padding: 20px 0 0;
-  -moz-box-shadow: rgba(0, 0, 0, 0.5) 0 0 20px 0 inset;
-  -webkit-box-shadow: rgba(0, 0, 0, 0.5) 0 0 20px 0 inset;
-  -o-box-shadow: rgba(0, 0, 0, 0.5) 0 0 20px 0 inset;
-  box-shadow: rgba(0, 0, 0, 0.5) 0 0 20px 0 inset;
-}
-#help h1 {
-  padding-left: 20px;
-}
-
 .markdown_syntax_toc_crumb {
   float: right !important;
   margin-left: 20px;


[47/50] [abbrv] allura git commit: [#7925] add test for commit view of a rename

Posted by he...@apache.org.
[#7925] add test for commit view of a rename


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/46baba14
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/46baba14
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/46baba14

Branch: refs/heads/hs/7925
Commit: 46baba14d7286953d72ac10cfa3385746a7b5444
Parents: 5ac9651
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Aug 5 15:30:11 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:38 2015 -0400

----------------------------------------------------------------------
 ForgeGit/forgegit/model/git_repo.py             |  1 -
 .../tests/functional/test_controllers.py        | 29 ++++++++++++++------
 2 files changed, 21 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/46baba14/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 8849a40..318f81f 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -675,7 +675,6 @@ class GitImplementation(M.RepositoryImplementation):
         while x < len(cmd_output):
             status = cmd_output[x][0]
             if status in ('R', 'C'):
-                # TODO: make sure we have a test for this
                 ratio = float(cmd_output[x][1:4]) / 100.0
                 files.append((status, {
                     'new': h.really_unicode(cmd_output[x + 2]),

http://git-wip-us.apache.org/repos/asf/allura/blob/46baba14/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 48969fc..4c363d2 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -820,8 +820,7 @@ class TestGitRename(TestController):
     @with_git
     def setup_with_tools(self):
         h.set_context('test', 'src-git', neighborhood='Projects')
-        repo_dir = pkg_resources.resource_filename(
-            'forgegit', 'tests/data')
+        repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data')
         c.app.repo.fs_path = repo_dir
         c.app.repo.status = 'ready'
         c.app.repo.name = 'testrename.git'
@@ -831,22 +830,36 @@ class TestGitRename(TestController):
         ThreadLocalORMSession.flush_all()
 
     def test_log(self):
-        resp = self.app.get(
-            '/src-git/ci/259c77dd6ee0e6091d11e429b56c44ccbf1e64a3/log/?path=/f2.txt')
+        # commit after the rename
+        resp = self.app.get('/src-git/ci/259c77dd6ee0e6091d11e429b56c44ccbf1e64a3/log/?path=/f2.txt')
         assert '<b>renamed from</b>' in resp
         assert '/f.txt' in resp
         assert '(27 Bytes)' in resp
         assert '(19 Bytes)' in resp
 
-        resp = self.app.get(
-            '/src-git/ci/fbb0644603bb6ecee3ebb62efe8c86efc9b84ee6/log/?path=/f.txt')
+        # commit before the rename
+        resp = self.app.get('/src-git/ci/fbb0644603bb6ecee3ebb62efe8c86efc9b84ee6/log/?path=/f.txt')
         assert '(19 Bytes)' in resp
         assert '(10 Bytes)' in resp
 
-        resp = self.app.get(
-            '/src-git/ci/7c09182e61af959e4f1fb0e354bab49f14ef810d/tree/f.txt')
+        # first commit, adding the file
+        resp = self.app.get('/src-git/ci/7c09182e61af959e4f1fb0e354bab49f14ef810d/tree/f.txt')
         assert "2 lines (1 with data), 10 Bytes" in resp
 
+    def test_commit(self):
+        # get the rename commit itself
+        resp = self.app.get('/src-git/ci/b120505a61225e6c14bee3e5b5862db81628c35c/')
+
+        # the top portion of the output
+        assert "<td>renamed" in resp
+        assert "f.txt -&gt; f2.txt" in resp
+
+        # the diff portion of the output
+        resp_no_ws = re.sub(r'\s+', '', str(resp))
+        assert '<a href="/p/test/src-git/ci/fbb0644603bb6ecee3ebb62efe8c86efc9b84ee6/tree/f.txt">f.txt</a>to<a href="/p/test/src-git/ci/b120505a61225e6c14bee3e5b5862db81628c35c/tree/f2.txt">f2.txt</a>'.replace(' ','') \
+               in resp_no_ws
+        assert '<span class="empty-diff">File was renamed.</span>' in resp
+
 
 class TestGitBranch(TestController):
     def setUp(self):


[09/50] [abbrv] allura git commit: [#7897] ticket:823 Do not call /nf/markdown_to_html when leaving preview mode

Posted by he...@apache.org.
[#7897] ticket:823 Do not call /nf/markdown_to_html when leaving preview mode


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9ff93371
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9ff93371
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9ff93371

Branch: refs/heads/hs/7925
Commit: 9ff93371b52690d381400621a740e6e13a951175
Parents: 42b5014
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 17 16:51:03 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/js/sf_markitup.js | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/9ff93371/Allura/allura/lib/widgets/resources/js/sf_markitup.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/sf_markitup.js b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
index 1dfdf4e..47cc6a7 100644
--- a/Allura/allura/lib/widgets/resources/js/sf_markitup.js
+++ b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
@@ -107,12 +107,13 @@ $(window).load(function() {
                 }, 1);
                 toolbar.className += ' active';
                 toolbar_div.className += ' disabled-for-preview';
+
+                /* Code modified by Allura is here */
+                var text = cm.getValue();
+                get_rendered_text(preview, text);
               }
-              var text = cm.getValue();
-              /* Code modified by Allura is here */
               $container.toggleClass('preview-active');
               $container.siblings('span.arw').toggleClass('preview-active');
-              get_rendered_text(preview, text);
             }
 
             function get_rendered_text(preview, text) {


[36/50] [abbrv] allura git commit: [#7925] Update commit web view to show copied and renamed changes

Posted by he...@apache.org.
[#7925] Update commit web view to show copied and renamed changes


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/73385a88
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/73385a88
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/73385a88

Branch: refs/heads/hs/7925
Commit: 73385a88dd6bc36adc4e1f8716b1fb3a621662bc
Parents: 04b87c6
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Mon Jul 27 16:11:50 2015 -0400
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:36 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py  | 4 ++--
 Allura/allura/templates/repo/commit.html | 5 +++++
 2 files changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/73385a88/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 5d03f64..0524589 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -565,8 +565,8 @@ class CommitBrowser(BaseController):
         diffs = self._commit.paged_diffs(start=start, end=start + limit)
         result['artifacts'] = [
             (t, f, 'blob' if tree.get_blob_by_path(f) else 'tree',
-            tree.get_blob_by_path(f) and tree.get_blob_by_path(f).is_text)
-            for t in ('added', 'removed', 'changed', 'copied')
+            tree.get_blob_by_path(f) and tree.get_blob_by_path(f).has_html_view)
+            for t in ('added', 'removed', 'changed', 'copied', 'renamed')
             for f in diffs[t]]
         count = diffs['total']
         result.update(dict(page=page, limit=limit, count=count))

http://git-wip-us.apache.org/repos/asf/allura/blob/73385a88/Allura/allura/templates/repo/commit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/commit.html b/Allura/allura/templates/repo/commit.html
index f029f52..f7206d4 100644
--- a/Allura/allura/templates/repo/commit.html
+++ b/Allura/allura/templates/repo/commit.html
@@ -1,3 +1,4 @@
+
 {#-
        Licensed to the Apache Software Foundation (ASF) under one
        or more contributor license agreements.  See the NOTICE file
@@ -119,6 +120,8 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
         <td><a href="#diff-{{loop.index}}">
             {% if type == 'copied' %}
               {{ '%s -> %s' % (h.really_unicode(file.old), h.really_unicode(file.new)) }}
+            {% elif type == 'renamed' %}
+              {{ '%s -> %s' % (h.really_unicode(file.old), h.really_unicode(file.new)) }}
             {% else %}
               {{h.really_unicode(file)}}
             {% endif %}
@@ -142,6 +145,8 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                 {% endif %}
             {% elif type == 'removed' %}
                 <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
+            {% elif type == 'renamed' %}
+                <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
             {% elif type == 'copied' %}
                 <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file.old))}}">{{h.really_unicode(file.old)}}</a>
                 to


[02/50] [abbrv] allura git commit: [#7897] ticket:820 Make preview bg transparent & remove borders

Posted by he...@apache.org.
[#7897] ticket:820 Make preview bg transparent & remove borders


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/78c0842c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/78c0842c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/78c0842c

Branch: refs/heads/hs/7925
Commit: 78c0842c00311124ad673dfa6dfdf6da6de33ea1
Parents: d78d322
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Jul 14 17:00:19 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 .../lib/widgets/resources/css/markitup_sf.css   | 20 ++++++++++++++++++++
 .../lib/widgets/resources/js/sf_markitup.js     |  5 ++++-
 2 files changed, 24 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/78c0842c/Allura/allura/lib/widgets/resources/css/markitup_sf.css
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/css/markitup_sf.css b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
index 5837469..059721a 100644
--- a/Allura/allura/lib/widgets/resources/css/markitup_sf.css
+++ b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
@@ -37,3 +37,23 @@
 .markdown_edit .editor-preview {
   z-index: 1001;  /* should always be under help modal */
 }
+.markdown_edit .editor-preview-active {
+  background-color: transparent;
+  position: relative;
+  padding: 0;
+}
+.markdown_edit.preview-active {
+  background-color: transparent;
+}
+.markdown_edit.preview-active .CodeMirror,
+.markdown_edit.preview-active .editor-toolbar {
+  border: 0;
+}
+.markdown_edit.preview-active .CodeMirror-scroll,
+.markdown_edit.preview-active .editor-statusbar,
+span.arw.preview-active {
+  display: none;
+}
+.markdown_edit.preview-active .editor-toolbar a {
+  background-color: transparent;
+}

http://git-wip-us.apache.org/repos/asf/allura/blob/78c0842c/Allura/allura/lib/widgets/resources/js/sf_markitup.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/sf_markitup.js b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
index b05f698..4162c9a 100644
--- a/Allura/allura/lib/widgets/resources/js/sf_markitup.js
+++ b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
@@ -80,7 +80,7 @@ $(window).load(function() {
             function show_preview(editor) {
               /*
                * This is pretty much the same as original SimpleMDE.togglePreview,
-               * but rendered text is fetched from the server.
+               * but rendered text is fetched from the server (see the comment bellow)
                * https://github.com/NextStepWebs/simplemde-markdown-editor/blob/1.2.1/source%20files/markdownify.js#L218-L249
                */
               var toolbar_div = document.getElementsByClassName('editor-toolbar')[0];
@@ -112,6 +112,9 @@ $(window).load(function() {
                 toolbar_div.className += ' disabled-for-preview';
               }
               var text = cm.getValue();
+              /* Code modified by Allura is here */
+              $container.toggleClass('preview-active');
+              $container.siblings('span.arw').toggleClass('preview-active');
               get_rendered_text(preview, text);
             }
 


[40/50] [abbrv] allura git commit: [#7925] fix template display: specify copy/rename, say file was binary instead of skip entirely, etc

Posted by he...@apache.org.
[#7925] fix template display: specify copy/rename, say file was binary instead of skip entirely, etc


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/3a8037c1
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/3a8037c1
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/3a8037c1

Branch: refs/heads/hs/7925
Commit: 3a8037c16afa1fb00f58f6e4aa307c505e5e1c61
Parents: 5adbb28
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 19:14:26 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:36 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py  | 16 +++++++++++-----
 Allura/allura/templates/repo/commit.html | 16 +++++++---------
 2 files changed, 18 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/3a8037c1/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 0524589..c17f06a 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -563,11 +563,17 @@ class CommitBrowser(BaseController):
         limit, page, start = g.handle_paging(limit, page,
                                              default=self.DEFAULT_PAGE_LIMIT)
         diffs = self._commit.paged_diffs(start=start, end=start + limit)
-        result['artifacts'] = [
-            (t, f, 'blob' if tree.get_blob_by_path(f) else 'tree',
-            tree.get_blob_by_path(f) and tree.get_blob_by_path(f).has_html_view)
-            for t in ('added', 'removed', 'changed', 'copied', 'renamed')
-            for f in diffs[t]]
+        result['artifacts'] = []
+        for t in ('added', 'removed', 'changed', 'copied', 'renamed'):
+            for f in diffs[t]:
+                if t in ('copied', 'renamed'):
+                    filepath = f['new']
+                else:
+                    filepath = f
+                is_text = filepath and tree.get_blob_by_path(filepath) and tree.get_blob_by_path(filepath).has_html_view
+                result['artifacts'].append(
+                    (t, f, 'blob' if tree.get_blob_by_path(f) else 'tree', is_text)
+                )
         count = diffs['total']
         result.update(dict(page=page, limit=limit, count=count))
         return result

http://git-wip-us.apache.org/repos/asf/allura/blob/3a8037c1/Allura/allura/templates/repo/commit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/commit.html b/Allura/allura/templates/repo/commit.html
index f7206d4..b0adabc 100644
--- a/Allura/allura/templates/repo/commit.html
+++ b/Allura/allura/templates/repo/commit.html
@@ -132,9 +132,8 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
 </table>
 
     {% for type, file, obj_type, is_text in artifacts %}
-        {% if is_text %}
-            <div class="inline-diff">
-                <h6>
+        <div class="inline-diff">
+            <h6>
             {% if type in ('added', 'changed') %}
                 {% if obj_type == 'tree' %}
                     <a href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
@@ -145,9 +144,7 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                 {% endif %}
             {% elif type == 'removed' %}
                 <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
-            {% elif type == 'renamed' %}
-                <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
-            {% elif type == 'copied' %}
+            {% elif type in ('copied', 'renamed') %}
                 <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file.old))}}">{{h.really_unicode(file.old)}}</a>
                 to
                 <a href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file.new))}}">{{h.really_unicode(file.new)}}</a>
@@ -156,14 +153,16 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
             <div id="diff-{{loop.index}}" class="inline-diff-body">
                 {% if type == 'removed' %}
                   <span class="empty-diff">File was removed.</span>
-                {% elif type == 'copied' %}
+                {% elif type in ('copied', 'renamed') %}
                   {% if file.ratio == 1 %}
-                    <span class="empty-diff">File was copied or renamed.</span>
+                    <span class="empty-diff">File was {{ type }}.</span>
                   {% else %}
                     {{g.highlight(file.diff, lexer='diff')}}
                   {% endif %}
                 {% elif obj_type == 'tree' %}
                     <span class="empty-diff">Directory.</span>
+                {% elif not is_text %}
+                    <span class="empty-diff">Binary file was {{ type }}.</span>
                 {% else %}
                     <img src="{{g.forge_static('images/spinner.gif')}}" class="loading_icon" alt="Loading..."/>
                     <script type="text/javascript">
@@ -175,7 +174,6 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                 {% endif %}
             </div>
         </div>
-        {% endif %}
     {% endfor %}
     {{ c.page_list.display(page=page, limit=limit, count=count) }}
 {% endblock %}


[24/50] [abbrv] allura git commit: [#7915] "contributing" cleanup

Posted by he...@apache.org.
[#7915] "contributing" cleanup


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/91870717
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/91870717
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/91870717

Branch: refs/heads/hs/7925
Commit: 91870717e1b2d3b481ece1c8c00ab5d57b392aa7
Parents: ff2fff4
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Aug 5 17:37:59 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Aug 5 17:53:23 2015 -0400

----------------------------------------------------------------------
 Allura/docs/development/contributing.rst     |   4 +-
 Allura/docs/getting_started/installation.rst |   2 +-
 CONTRIBUTING                                 | 174 ----------------------
 3 files changed, 4 insertions(+), 176 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/91870717/Allura/docs/development/contributing.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/development/contributing.rst b/Allura/docs/development/contributing.rst
index 2dff6ad..a3b8ba4 100644
--- a/Allura/docs/development/contributing.rst
+++ b/Allura/docs/development/contributing.rst
@@ -15,6 +15,8 @@
        specific language governing permissions and limitations
        under the License.
 
+.. _contributing:
+
 ************
 Contributing
 ************
@@ -36,7 +38,7 @@ Installing Allura
 -----------------
 Before hacking on Allura, you'll need to get an Allura instance up and running
 so you can see and test the changes you make. You can install Allura from
-scratch, or by using our pre-built Vagrant image. Instructions for these
+scratch, or by using our Docker container images. Instructions for these
 approaches can be found here:
 
 * :ref:`Install from scratch <step-by-step-install>`

http://git-wip-us.apache.org/repos/asf/allura/blob/91870717/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index d43d52d..5ad62a7 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -220,7 +220,7 @@ Extra
 * Ask questions and discuss Allura on the `allura-dev mailing list <http://mail-archives.apache.org/mod_mbox/allura-dev/>`_
 * Run the test suite (slow): :code:`$ ALLURA_VALIDATION=none ./run_tests`
 * File bug reports at https://forge-allura.apache.org/p/allura/tickets/new/ (login required)
-* Contribute code according to `this guide <https://forge-allura.apache.org/p/allura/wiki/Contributing%20Code/>`_
+* Contribute code according to :ref:`this guide <contributing>`
 
 .. _docker-install:
 

http://git-wip-us.apache.org/repos/asf/allura/blob/91870717/CONTRIBUTING
----------------------------------------------------------------------
diff --git a/CONTRIBUTING b/CONTRIBUTING
deleted file mode 100644
index 88ae8ce..0000000
--- a/CONTRIBUTING
+++ /dev/null
@@ -1,174 +0,0 @@
-       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.
-
-ABOUT ALLURA
-
-Allura is an open source implementation of a software "forge", a
-web-site that manages source code repositories, bug reports,
-discussions, mailing lists, wiki pages, blogs and more for any
-number of individual projects.
-
-SourceForge.net is running an instance of Allura (aka New Forge, or
-Forge 2.0); and Allura itself is a project managed there:
-
-  <https://allura.apache.org/>
-
-The source for Allura is available there from a Git repo under the
-Apache License, Version 2.0.
-
-  <http://www.apache.org/licenses/LICENSE-2.0>
-
-Allura is written in Python and leverages a great many existing Python
-packages (see requirements.txt and friends).  It comes with tests which
-we run with nose (see <http://somethingaboutorange.com/mrl/projects/nose/1.0.0/>).
-It is extensible in several ways, most importantly via the notion of
-"tools" based on allura.Application; but also with themes,
-authentication, and various other pluggable-APIs.
-
-CONTRIBUTING
-
-Allura is an effort _for_ the community: an open source platform for
-sharing development.  We think it should be _of_ the community as well.
-We want to encourage community involvement in development, testing and
-design.  We do that with a public git repo, a bug tracker, a discussion
-list and an IRC channel.
-
-
-- REPORTING BUGS
-
-Report bugs to our public tracker at:
-
-  <https://forge-allura.apache.org/p/allura/tickets/>
-
-Four things make for a good bug report:
-
-  + it's not a duplicate of an existing bug
-
-  + it has a clear description of what was expected vs. what actually
-    happened and why what actually happened was wrong
-
-  + it has a recipe as simple as possible to reproduce it
-
-  + it describes the environment in which the bug happens, i.e., your
-    os, browser, and browser version; or if you're running your own
-    forge -- the relevant details of the host os and supporting tools
-
-Other things that increase the value of a bug report but aren't always
-possible or applicable:
-
-  + screen shots
-
-  + code (to be added to the automated tests) that tests for the problem
-
-  + patches to fix the problem
-
-
-- GETTING THE CODE
-
-The code is self-hosted in a public git repository.  Get it by cloning:
-
-  git clone https://git-wip-us.apache.org/repos/asf/allura.git allura
-
-- CONTRIBUTING CODE
-
-Develop and test your patches locally and then get them to us in one of
-two ways:
-
-  + push your changes up to your 'forked' repo, and from there send us
-    a merge request
-
-  + attach a patch file to a ticket
-
-Things your patch-sequence must have/do:
-
-  + follow PEP-8 <http://www.python.org/dev/peps/pep-0008/> coding
-    guidelines
-
-  + contain appropriate tests to be added to the automated testing
-    machinery
-
-  + pass existing tests (and/or fix existing tests that need to change)
-
-  + be divided into an appropriate number of commits, one per reasonable
-    "chunk" of functionality
-
-Things your patch will have before it can be merged into branch 'dev' or
-'master':
-
-  + Discussion either on the mailing list or in the merge request, where
-    you submitted it
-
-  + Code-review (possibly many times as you re-work your patches in
-    response to discussion)
-
-Very small patches might not need much discussion.
-
-
-- CONTRIBUTING TO THE DISCUSSION
-
-We intend to develop "out in the open", which means having a public
-discussion where we talk about new features, submitted patches, bugs,
-direction, and deployment.  You can join in the discussion on the
-mailing list:
-
-  <http://mail-archives.apache.org/mod_mbox/allura-dev/>
-
-
-- ASKING QUESTIONS
-
-First, is your question already answered in the FAQ?
-
-  <https://forge-allura.apache.org/p/allura/wiki/FAQ/>
-
-If not, then the right place to ask is either the mailing list (above)
-or the IRC channel:
-
-  <irc://irc.freenode.com:6667/#sourceforge>
-
-
-- OUR DEVELOPMENT MODEL
-
-Our model is a somewhat scaled-down version of how the Git project
-itself is run.  We have two main branches
-
-  + master: release quality
-
-  + dev: integration branch for commits expected to go to master
-
-  + feature branches not yet ready for integration testing, starting
-    with the two character initials of the author, e.g., db/1368 for Dave
-    Brondsema's work on bug [#1368] or wo/contributing for Wolf's work on
-    the CONTRIBUTING doc
-
-'master' and 'dev' are stable; they will never be rewound or rebased.
-Feature branches are typically cut from 'dev', and usually rebased to
-'dev' just before they are merged there.  In the meanwhile they may be
-rebased or rewound as necessary.  Being on 'dev' is not a guarantee that
-a commit will make it to master.  Anything that turns out to not
-actually be ready will be reverted.
-
-'dev' will always contain 'master'.  Emergency fixes may go directly to
-'master' which would then immediately be merged down into 'dev'.
-
-As we get more contributors and start having "patch-churn", we will
-re-evaluate a three-branch model, like Git. The third branch would be
-'pu' (for "proposed update").
-
-We expect that people deploying the code will deploy from 'master' or
-from a release tag.  We expect that people experimenting with the code
-will deploy from 'dev' or from their own feature branches or integration
-branches cut from 'dev'.


[31/50] [abbrv] allura git commit: bump up run_tests multiprocessing timeout

Posted by he...@apache.org.
bump up run_tests multiprocessing timeout


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/032c2ed8
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/032c2ed8
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/032c2ed8

Branch: refs/heads/hs/7925
Commit: 032c2ed88e4882bc4018f8632b9a3f8d5239b8f4
Parents: 8a226bd
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Aug 7 19:50:26 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri Aug 7 19:50:26 2015 +0000

----------------------------------------------------------------------
 run_tests | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/032c2ed8/run_tests
----------------------------------------------------------------------
diff --git a/run_tests b/run_tests
index c91362c..4640244 100755
--- a/run_tests
+++ b/run_tests
@@ -30,7 +30,7 @@ import textwrap
 CPUS = multiprocessing.cpu_count()
 CONCURRENT_SUITES = (CPUS // 4) or CPUS
 CONCURRENT_TESTS = max(CPUS // CONCURRENT_SUITES, 2)  # need at least two, see thread http://mail-archives.apache.org/mod_mbox/allura-dev/201409.mbox/%3C541C5756.1020604%40brondsema.net%3E
-PROC_TIMEOUT = 180
+PROC_TIMEOUT = 360
 
 ALT_PKG_PATHS = {
     'Allura': 'allura/tests/',


[14/50] [abbrv] allura git commit: [#7897] ticket:832 Remove list margin

Posted by he...@apache.org.
[#7897] ticket:832 Remove list margin


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/8f5dd483
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/8f5dd483
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/8f5dd483

Branch: refs/heads/hs/7925
Commit: 8f5dd48361845866271b2d59ca82c625f1884e53
Parents: b89befe
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 29 13:12:10 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Wed Jul 29 13:12:10 2015 +0300

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8f5dd483/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index ca78000..055583e 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -2642,7 +2642,6 @@ div.attachment_thumb .file_type span {
   float: none;
   padding-left: 1em;
   list-style-type: disc;
-  margin-bottom: 5px !important;
 }
 #comment .edit_post_form ul,
 #comment .reply_post_form ul {


[16/50] [abbrv] allura git commit: [#7947] remove unnecessary line breakage

Posted by he...@apache.org.
[#7947] remove unnecessary line breakage


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/556a99e9
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/556a99e9
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/556a99e9

Branch: refs/heads/hs/7925
Commit: 556a99e9d986a9ebff4b84c36bf64886da02e4fd
Parents: 7075554
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Aug 3 18:10:54 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Aug 3 18:10:54 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/markdown_extensions.py | 36 +++++++++------------------
 Allura/allura/model/project.py           |  3 +--
 2 files changed, 13 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/556a99e9/Allura/allura/lib/markdown_extensions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/markdown_extensions.py b/Allura/allura/lib/markdown_extensions.py
index 9a68e1a..83e8069 100644
--- a/Allura/allura/lib/markdown_extensions.py
+++ b/Allura/allura/lib/markdown_extensions.py
@@ -74,18 +74,14 @@ class CommitMessageExtension(markdown.Extension):
         md.registerExtension(self)
         # remove default preprocessors and add our own
         md.preprocessors.clear()
-        md.preprocessors['trac_refs'] = PatternReplacingProcessor(
-            TracRef1(), TracRef2(), TracRef3(self.app))
+        md.preprocessors['trac_refs'] = PatternReplacingProcessor(TracRef1(), TracRef2(), TracRef3(self.app))
         # remove all inlinepattern processors except short refs and links
         md.inlinePatterns.clear()
-        md.inlinePatterns["link"] = markdown.inlinepatterns.LinkPattern(
-            markdown.inlinepatterns.LINK_RE, md)
-        md.inlinePatterns['short_reference'] = ForgeLinkPattern(
-            markdown.inlinepatterns.SHORT_REF_RE, md, ext=self)
+        md.inlinePatterns["link"] = markdown.inlinepatterns.LinkPattern(markdown.inlinepatterns.LINK_RE, md)
+        md.inlinePatterns['short_reference'] = ForgeLinkPattern(markdown.inlinepatterns.SHORT_REF_RE, md, ext=self)
         # remove all default block processors except for paragraph
         md.parser.blockprocessors.clear()
-        md.parser.blockprocessors['paragraph'] = \
-            markdown.blockprocessors.ParagraphProcessor(md.parser)
+        md.parser.blockprocessors['paragraph'] = markdown.blockprocessors.ParagraphProcessor(md.parser)
         # wrap artifact link text in square brackets
         self.forge_link_tree_processor = ForgeLinkTreeProcessor(md)
         md.treeprocessors['links'] = self.forge_link_tree_processor
@@ -253,31 +249,23 @@ class ForgeExtension(markdown.Extension):
         # https://github.com/waylan/Python-Markdown/issues/52
         md.preprocessors['html_block'].markdown_in_raw = True
         md.preprocessors['fenced-code'] = FencedCodeProcessor()
-        md.preprocessors.add('plain_text_block',
-                             PlainTextPreprocessor(md), "_begin")
-        md.preprocessors.add(
-            'macro_include', ForgeMacroIncludePreprocessor(md), '_end')
+        md.preprocessors.add('plain_text_block', PlainTextPreprocessor(md), "_begin")
+        md.preprocessors.add('macro_include', ForgeMacroIncludePreprocessor(md), '_end')
         # this has to be before the 'escape' processor, otherwise weird
         # placeholders are inserted for escaped chars within urls, and then the
         # autolink can't match the whole url
-        md.inlinePatterns.add('autolink_without_brackets', AutolinkPattern(
-            r'(http(?:s?)://[a-zA-Z0-9./\-\\_%?&=+#;~:!]+)', md), '<escape')
+        md.inlinePatterns.add('autolink_without_brackets', AutolinkPattern(r'(http(?:s?)://[a-zA-Z0-9./\-\\_%?&=+#;~:!]+)', md), '<escape')
         # replace the link pattern with our extended version
-        md.inlinePatterns['link'] = ForgeLinkPattern(
-            markdown.inlinepatterns.LINK_RE, md, ext=self)
-        md.inlinePatterns['short_reference'] = ForgeLinkPattern(
-            markdown.inlinepatterns.SHORT_REF_RE, md, ext=self)
+        md.inlinePatterns['link'] = ForgeLinkPattern(markdown.inlinepatterns.LINK_RE, md, ext=self)
+        md.inlinePatterns['short_reference'] = ForgeLinkPattern(markdown.inlinepatterns.SHORT_REF_RE, md, ext=self)
         # macro must be processed before links
-        md.inlinePatterns.add(
-            'macro', ForgeMacroPattern(MACRO_PATTERN, md, ext=self), '<link')
+        md.inlinePatterns.add('macro', ForgeMacroPattern(MACRO_PATTERN, md, ext=self), '<link')
         self.forge_link_tree_processor = ForgeLinkTreeProcessor(md)
         md.treeprocessors['links'] = self.forge_link_tree_processor
         # Sanitize HTML
         md.postprocessors['sanitize_html'] = HTMLSanitizer()
-        # Rewrite all relative links that don't start with . to have a '../'
-        # prefix
-        md.postprocessors['rewrite_relative_links'] = RelativeLinkRewriter(
-            make_absolute=self._is_email)
+        # Rewrite all relative links that don't start with . to have a '../' prefix
+        md.postprocessors['rewrite_relative_links'] = RelativeLinkRewriter(make_absolute=self._is_email)
         # Put a class around markdown content for custom css
         md.postprocessors['add_custom_class'] = AddCustomClass()
         md.postprocessors['mark_safe'] = MarkAsSafe()

http://git-wip-us.apache.org/repos/asf/allura/blob/556a99e9/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index b45af77..cef25bc 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -859,8 +859,7 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
         named_roles = security.RoleCache(
             g.credentials,
             g.credentials.project_roles(project_id=self.root_project._id).named)
-        uids = [
-            uid for uid in named_roles.userids_that_reach if uid is not None]
+        uids = [uid for uid in named_roles.userids_that_reach if uid is not None]
         return list(User.query.find({'_id': {'$in': uids}, 'disabled': False, 'pending': False}))
 
     def users_with_role(self, *role_names):


[42/50] [abbrv] allura git commit: [#7925] use some variables to clean up some repetition in the commit template

Posted by he...@apache.org.
[#7925] use some variables to clean up some repetition in the commit template


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/1919ec09
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/1919ec09
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/1919ec09

Branch: refs/heads/hs/7925
Commit: 1919ec0959c6883d6239d060bf19d44e02b4df04
Parents: b950a1f
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 22:42:54 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:37 2015 -0400

----------------------------------------------------------------------
 Allura/allura/templates/repo/commit.html | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/1919ec09/Allura/allura/templates/repo/commit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/commit.html b/Allura/allura/templates/repo/commit.html
index 06da620..adf57b2 100644
--- a/Allura/allura/templates/repo/commit.html
+++ b/Allura/allura/templates/repo/commit.html
@@ -135,22 +135,25 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
         <div class="inline-diff">
             <h6>
             {% if type in ('added', 'changed') %}
-                {% if obj_type == 'tree' %}
-                    <a href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
-                {% else %}
-                    <a href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
-                    <a class="commit-diff-link" href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file))}}?diff={{prev[0]._id if prev else ''}}">Diff</a>
-                    <a class="commit-diff-link switch-diff-format-link" data-diformat="{{session.diformat}}" data-diffid="diff-{{loop.index}}" href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file))}}?barediff={{prev[0]._id if prev else ''}}">Switch to {{'unified' if session.diformat == 'sidebyside' else 'side-by-side'}} view</a>
+                {% set file_url = commit.url() + 'tree/' + h.urlquote(h.really_unicode(file)) %}
+                <a href="{{ file_url }}">{{h.really_unicode(file)}}</a>
+                {% if obj_type != 'tree' %}
+                    {% set diff_url = file_url + '?barediff=' + (prev[0]._id if prev else '') %}
+                    <a class="commit-diff-link" href="{{ diff_url.replace('?barediff=', '?diff=') }}">Diff</a>
+                    <a class="commit-diff-link switch-diff-format-link" data-diformat="{{session.diformat}}" data-diffid="diff-{{loop.index}}" href="{{ diff_url }}">Switch to {{'unified' if session.diformat == 'sidebyside' else 'side-by-side'}} view</a>
                 {% endif %}
             {% elif type == 'removed' %}
-                <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
+                {% set file_url = prev[0].url() + 'tree/' + h.urlquote(h.really_unicode(file)) %}
+                <a href="{{ file_url }}">{{h.really_unicode(file)}}</a>
             {% elif type in ('copied', 'renamed') %}
                 <a href="{{prev[0].url()}}tree/{{h.urlquote(h.really_unicode(file.old))}}">{{h.really_unicode(file.old)}}</a>
                 to
-                <a href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file.new))}}">{{h.really_unicode(file.new)}}</a>
+                {% set new_file_url = commit.url() + 'tree/' + h.urlquote(h.really_unicode(file.new)) %}
+                <a href="{{ new_file_url }}">{{h.really_unicode(file.new)}}</a>
                 {% if file.ratio != 1 %}
-                    <a class="commit-diff-link" href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file['new']))}}?diff={{prev[0]._id if prev else ''}}&prev_file={{h.urlquote(h.really_unicode(file['old']))}}">Diff</a>
-                    <a class="commit-diff-link switch-diff-format-link" data-diformat="{{session.diformat}}" data-diffid="diff-{{loop.index}}" href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file['new']))}}?barediff={{prev[0]._id if prev else ''}}&prev_file={{h.urlquote(h.really_unicode(file['old']))}}">Switch to {{'unified' if session.diformat == 'sidebyside' else 'side-by-side'}} view</a>
+                    {% set diff_url = new_file_url + '?barediff=' + (prev[0]._id if prev else '') + '&prev_file=' + h.urlquote(h.really_unicode(file['old'])) %}
+                    <a class="commit-diff-link" href="{{ diff_url.replace('?barediff=', '?diff=') }}">Diff</a>
+                    <a class="commit-diff-link switch-diff-format-link" data-diformat="{{session.diformat}}" data-diffid="diff-{{loop.index}}" href="{{diff_url}}">Switch to {{'unified' if session.diformat == 'sidebyside' else 'side-by-side'}} view</a>
                 {% endif %}
             {% endif %}
             </h6>
@@ -165,7 +168,7 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                     <script type="text/javascript">
                       diff_queue.push({
                         selector: '#diff-{{loop.index}}',
-                        url: '{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file['new']))}}?barediff={{prev[0]._id if prev else ''}}&prev_file={{h.urlquote(h.really_unicode(file['old']))}}'
+                        url: '{{diff_url}}'
                       });
                     </script>
                   {% endif %}
@@ -178,7 +181,7 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                     <script type="text/javascript">
                       diff_queue.push({
                         selector: '#diff-{{loop.index}}',
-                        url: '{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file))}}?barediff={{prev[0]._id if prev else ''}}'
+                        url: '{{diff_url}}'
                       });
                     </script>
                 {% endif %}


[17/50] [abbrv] allura git commit: [#7947] fix minor HTML changes in tests, also artifact links now have trailing slashes again (they went away in [8da7c57] for some reason)

Posted by he...@apache.org.
[#7947] fix minor HTML changes in tests, also artifact links now have trailing slashes again (they went away in [8da7c57] for some reason)


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/dd3ca5bf
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/dd3ca5bf
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/dd3ca5bf

Branch: refs/heads/hs/7925
Commit: dd3ca5bf6fc5be91a2ef29012c6a59c62cf85a8a
Parents: e0e2f0c
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Aug 3 18:47:15 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Aug 3 18:55:26 2015 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_root.py     |   2 +-
 Allura/allura/tests/test_globals.py             | 114 ++++++++++---------
 Allura/allura/tests/test_helpers.py             |   2 +-
 .../forgeblog/tests/unit/test_blog_post.py      |   2 +-
 .../forgetracker/tests/functional/test_root.py  |  10 +-
 5 files changed, 68 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dd3ca5bf/Allura/allura/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py
index 8f29b31..bc54d65 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -149,7 +149,7 @@ class TestRootController(TestController):
         n = M.Neighborhood.query.get(name='Projects')
         r = self.app.get(
             '/nf/markdown_to_html?markdown=*aaa*bb[wiki:Home]&project=test&app=bugs&neighborhood=%s' % n._id, validate_chunk=True)
-        assert '<p><em>aaa</em>bb<a class="alink" href="/p/test/wiki/Home">[wiki:Home]</a></p>' in r, r
+        assert '<p><em>aaa</em>bb<a class="alink" href="/p/test/wiki/Home/">[wiki:Home]</a></p>' in r, r
 
     def test_slash_redirect(self):
         self.app.get('/p', status=301)

http://git-wip-us.apache.org/repos/asf/allura/blob/dd3ca5bf/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 91565ae..0203969 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -48,6 +48,9 @@ from allura.tests import decorators as td
 from forgewiki import model as WM
 from forgeblog import model as BM
 
+def squish_spaces(text):
+    return re.sub(r'\s+', ' ', text)
+
 
 def setUp():
     """Method called by nose once before running the package.  Some functions need it run again to reset data"""
@@ -210,12 +213,14 @@ def test_macro_members():
     p_test.add_user(M.User.by_username('test-user'), ['Developer'])
     p_test.add_user(M.User.by_username('test-user-0'), ['Member'])
     ThreadLocalORMSession.flush_all()
-    r = g.markdown_wiki.convert('[[members limit=2]]')
-    assert_equal(r, '<div class="markdown_content"><h6>Project Members:</h6>\n'
-                 '<ul class="md-users-list">\n'
-                 '<li><a href="/u/test-admin">Test Admin</a> (admin)</li><li><a href="/u/test-user">Test User</a></li>\n'
-                 '<li class="md-users-list-more"><a href="/p/test/_members">All Members</a></li>\n'
-                 '</ul>\n'
+    r = g.markdown_wiki.convert('[[members limit=2]]').replace('\t','').replace('\n','')
+    assert_equal(r,
+                 '<div class="markdown_content"><h6>Project Members:</h6>'
+                 '<ul class="md-users-list">'
+                 '<li><a href="/u/test-admin/">Test Admin</a> (admin)</li>'
+                 '<li><a href="/u/test-user/">Test User</a></li>'
+                 '<li class="md-users-list-more"><a href="/p/test/_members">All Members</a></li>'
+                 '</ul>'
                  '</div>')
 
 
@@ -224,10 +229,11 @@ def test_macro_members_escaping():
     user = M.User.by_username('test-admin')
     user.display_name = u'Test Admin <script>'
     r = g.markdown_wiki.convert('[[members]]')
-    assert_equal(r, u'<div class="markdown_content"><h6>Project Members:</h6>\n'
-                 u'<ul class="md-users-list">\n'
-                 u'<li><a href="/u/test-admin">Test Admin &lt;script&gt;</a> (admin)</li>\n'
-                 u'</ul>\n</div>')
+    assert_equal(r.replace('\n', '').replace('\t', ''),
+                 u'<div class="markdown_content"><h6>Project Members:</h6>'
+                 u'<ul class="md-users-list">'
+                 u'<li><a href="/u/test-admin/">Test Admin &lt;script&gt;</a> (admin)</li>'
+                 u'</ul></div>')
 
 
 @with_setup(setUp)
@@ -236,8 +242,11 @@ def test_macro_project_admins():
     user.display_name = u'Test Ådmin <script>'
     with h.push_context('test', neighborhood='Projects'):
         r = g.markdown_wiki.convert('[[project_admins]]')
-    assert_equal(
-        r, u'<div class="markdown_content"><h6>Project Admins:</h6>\n<ul class="md-users-list">\n<li><a href="/u/test-admin">Test \xc5dmin &lt;script&gt;</a></li>\n</ul>\n</div>')
+    assert_equal(r.replace('\n', ''),
+                 u'<div class="markdown_content"><h6>Project Admins:</h6>'
+                 u'<ul class="md-users-list">'
+                 u'    <li><a href="/u/test-admin/">Test \xc5dmin &lt;script&gt;</a></li>'
+                 u'</ul></div>')
 
 
 @with_setup(setUp)
@@ -249,7 +258,7 @@ def test_macro_project_admins_one_br():
     with h.push_config(c, project=p_test):
         r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]')
 
-    assert not '</a><br /><br /><a href=' in r, r
+    assert not '</a><br/><br/><a href=' in r, r
     assert '</a></li><li><a href=' in r, r
 
 
@@ -272,17 +281,17 @@ def test_macro_include_no_extra_br():
         md = '[[include ref=Include_1]]\n[[include ref=Include_2]]\n[[include ref=Include_3]]'
         html = g.markdown_wiki.convert(md)
 
-    expected_html = '''
-<div class="markdown_content">
-<p>
-<div><div class="markdown_content"><p>included page 1</p></div></div>
-<div><div class="markdown_content"><p>included page 2</p></div></div>
-<div><div class="markdown_content"><p>included page 3</p></div></div>
-</p>
-<p></p>
+    expected_html = '''<div class="markdown_content"><p></p><div>
+<div class="markdown_content"><p>included page 1</p></div>
+</div>
+<div>
+<div class="markdown_content"><p>included page 2</p></div>
+</div>
+<div>
+<div class="markdown_content"><p>included page 3</p></div>
 </div>
-'''.strip().replace('\n', '')
-    assert html.strip().replace('\n', '') == expected_html, html
+<p></p></div>'''
+    assert_equal(squish_spaces(html), squish_spaces(expected_html))
 
 @with_setup(setUp, tearDown)
 @td.with_wiki
@@ -324,10 +333,9 @@ def test_macro_embed(oembed_fetch):
         "html": '<iframe width="480" height="270" src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" frameborder="0" allowfullscreen></iframe>)',
         "title": "Nature's 3D Printer: MIND BLOWING Cocoon in Rainforest - Smarter Every Day 94",
     }
-    r = g.markdown_wiki.convert(
-        '[[embed url=http://www.youtube.com/watch?v=kOLpSPEA72U]]')
-    assert_in('<div class="grid-20"><iframe height="270" src="https://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe>\n</div>',
-              r)
+    r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=kOLpSPEA72U]]')
+    assert_in('<div class="grid-20"><iframe height="270" src="https://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe></div>',
+              r.replace('\n', ''))
 
 
 def test_macro_embed_notsupported():
@@ -357,29 +365,29 @@ def test_wiki_artifact_links():
     assert 'See <span>[18:13:49]</span>' in text, text
     with h.push_context('test', 'wiki', neighborhood='Projects'):
         text = g.markdown.convert('Read [here](Home) about our project')
-        assert '<a class="" href="/p/test/wiki/Home">here</a>' in text, text
+        assert '<a class="" href="/p/test/wiki/Home/">here</a>' in text, text
         text = g.markdown.convert('[Go home](test:wiki:Home)')
-        assert '<a class="" href="/p/test/wiki/Home">Go home</a>' in text, text
+        assert '<a class="" href="/p/test/wiki/Home/">Go home</a>' in text, text
         text = g.markdown.convert('See [test:wiki:Home]')
-        assert '<a class="alink" href="/p/test/wiki/Home">[test:wiki:Home]</a>' in text, text
+        assert '<a class="alink" href="/p/test/wiki/Home/">[test:wiki:Home]</a>' in text, text
 
 
 def test_markdown_links():
     with patch.dict(tg.config, {'nofollow_exempt_domains': 'foobar.net'}):
-        text = g.markdown.convert(
-            'Read [here](http://foobar.net/) about our project')
-        assert_in('class="" href="http://foobar.net">here</a> about', text)
+        text = g.markdown.convert('Read [here](http://foobar.net/) about our project')
+        assert_in('class="" href="http://foobar.net/">here</a> about', text)
 
-    text = g.markdown.convert(
-        'Read [here](http://foobar.net/) about our project')
-    assert_in('class="" href="http://foobar.net" rel="nofollow">here</a> about', text)
+    text = g.markdown.convert('Read [here](http://foobar.net/) about our project')
+    assert_in('class="" href="http://foobar.net/" rel="nofollow">here</a> about', text)
 
     text = g.markdown.convert('Read [here](/p/foobar/blah) about our project')
     assert_in('class="" href="/p/foobar/blah">here</a> about', text)
 
+    text = g.markdown.convert('Read [here](/p/foobar/blah/) about our project')
+    assert_in('class="" href="/p/foobar/blah/">here</a> about', text)
+
     text = g.markdown.convert('Read <http://foobar.net/> about our project')
-    assert_in(
-        'href="http://foobar.net" rel="nofollow">http://foobar.net/</a> about', text)
+    assert_in('href="http://foobar.net/" rel="nofollow">http://foobar.net/</a> about', text)
 
 
 def test_markdown_and_html():
@@ -390,11 +398,9 @@ def test_markdown_and_html():
 
 def test_markdown_within_html():
     with h.push_context('test', neighborhood='Projects'):
-        r = g.markdown_wiki.convert(
-            '<div style="float:left" markdown>**blah**</div>')
-    assert '''<div style="float: left;">
-<p><strong>blah</strong></p>
-</div>''' in r, r
+        r = g.markdown_wiki.convert('<div style="float:left" markdown>**blah**</div>')
+    assert_in('<div style="float: left;"><p><strong>blah</strong></p></div>',
+              r.replace('\n', ''))
 
 
 def test_markdown_with_html_comments():
@@ -413,16 +419,15 @@ def test_markdown_big_text():
 def test_markdown_basics():
     with h.push_context('test', 'wiki', neighborhood='Projects'):
         text = g.markdown.convert('# Foo!\n[Home]')
-        assert '<a class="alink" href="/p/test/wiki/Home">[Home]</a>' in text, text
+        assert '<a class="alink" href="/p/test/wiki/Home/">[Home]</a>' in text, text
         text = g.markdown.convert('# Foo!\n[Rooted]')
         assert '<a href=' not in text, text
 
-    assert '<br' in g.markdown.convert(
-        'Multi\nLine'), g.markdown.convert('Multi\nLine')
+    assert '<br' in g.markdown.convert('Multi\nLine'), g.markdown.convert('Multi\nLine')
     assert '<br' not in g.markdown.convert('Multi\n\nLine')
 
     g.markdown.convert("<class 'foo'>")  # should not raise an exception
-    assert '<br>' not in g.markdown.convert('''# Header
+    assert '<br' not in g.markdown.convert('''# Header
 
 Some text in a regular paragraph
 
@@ -446,7 +451,7 @@ def test_markdown_autolink():
     # beginning of doc
     assert_in('<a href=', g.markdown.convert('http://domain.net abc'))
     # beginning of a line
-    assert_in('<br />\n<a href="http://',
+    assert_in('<br/>\n<a href="http://',
               g.markdown.convert('foobar\nhttp://domain.net abc'))
     # no conversion of these urls:
     assert_in('a blahttp://sdf.com z',
@@ -461,8 +466,7 @@ def test_markdown_autolink():
 def test_markdown_autolink_with_escape():
     # \_ is unnecessary but valid markdown escaping and should be considered as a regular underscore
     # (it occurs during html2text conversion during project migrations)
-    r = g.markdown.convert(
-        'a http://www.phpmyadmin.net/home\_page/security/\#target b')
+    r = g.markdown.convert('a http://www.phpmyadmin.net/home\_page/security/\#target b')
     assert 'href="http://www.phpmyadmin.net/home_page/security/#target"' in r, r
 
 
@@ -588,7 +592,7 @@ def test_myprojects_macro():
     for p in c.user.my_projects():
         if p.deleted or p.is_nbhd_project:
             continue
-        proj_title = '<h2><a href="%s">%s</a></h2>' % (p.url().rstrip('/'), p.name)
+        proj_title = '<h2><a href="%s">%s</a></h2>' % (p.url(), p.name)
         assert_in(proj_title, r)
 
     h.set_context('u/test-user-1', 'wiki', neighborhood='Users')
@@ -597,7 +601,7 @@ def test_myprojects_macro():
     for p in user.my_projects():
         if p.deleted or p.is_nbhd_project:
             continue
-        proj_title = '<h2><a href="%s">%s</a></h2>' % (p.url().rstrip('/'), p.name)
+        proj_title = '<h2><a href="%s">%s</a></h2>' % (p.url(), p.name)
         assert_in(proj_title, r)
 
 
@@ -625,9 +629,11 @@ def test_hideawards_macro():
 
     with h.push_context(p_nbhd.neighborhood_project._id):
         r = g.markdown_wiki.convert('[[projects]]')
-        assert '<div class="feature">\n<a href="http://award.org" title="Winner!" rel="nofollow">Award short</a>\n</div>' in r, r
+        assert_in('<div class="feature"> <a href="http://award.org" rel="nofollow" title="Winner!">Award short</a> </div>',
+                  squish_spaces(r))
+
         r = g.markdown_wiki.convert('[[projects show_awards_banner=False]]')
-        assert '<div class="feature">\n<a href="http://award.org" title="Winner!" rel="nofollow">Award short</a>\n</div>' not in r, r
+        assert_not_in('Award short', r)
 
 
 def get_project_names(r):

http://git-wip-us.apache.org/repos/asf/allura/blob/dd3ca5bf/Allura/allura/tests/test_helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index 49032eb..22d5b94 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -250,7 +250,7 @@ def test_render_any_markup_formatting():
                   '<div class="markdown_content"><h3 id="foo">foo</h3>\n'
                   '<div class="codehilite"><pre><span class="nt">'
                   '&lt;script&gt;</span>alert(1)<span class="nt">'
-                  '&lt;/script&gt;</span> bar\n</pre></div>\n</div>')
+                  '&lt;/script&gt;</span> bar\n</pre></div>\n\n</div>')
 
 
 class AuditLogMock(Mock):

http://git-wip-us.apache.org/repos/asf/allura/blob/dd3ca5bf/ForgeBlog/forgeblog/tests/unit/test_blog_post.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/unit/test_blog_post.py b/ForgeBlog/forgeblog/tests/unit/test_blog_post.py
index 34842c5..fadfcf0 100644
--- a/ForgeBlog/forgeblog/tests/unit/test_blog_post.py
+++ b/ForgeBlog/forgeblog/tests/unit/test_blog_post.py
@@ -132,6 +132,6 @@ class TestHtmlPreview(BlogTestWithModel):
                     'fugiat nulla pariatur. Excepteur sint occaecat cupidatat '
                     'non proident, sunt in culpa qui officia deserunt mollit '
                     'anim id est laborum.... '
-                    '<a class="" href="/p/test/blog/%s/%02i/untitled">'
+                    '<a class="" href="/p/test/blog/%s/%02i/untitled/">'
                     'read more</a></p></div>') % (now.year, now.month)
         assert_equal(self._make_post(text).html_text_preview, expected)

http://git-wip-us.apache.org/repos/asf/allura/blob/dd3ca5bf/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 89041d7..47c9aab 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -984,8 +984,8 @@ class TestFunctionalController(TrackerTestController):
         assert_not_in('Tickets: <s>#1</s>', r)
         assert_in('Tickets: <s>#2</s>', r)
 
-        assert_in('<a class="alink" href="/p/test/bugs/1">[#1]</a>', r.body)
-        assert_in('<a class="alink strikethrough" href="/p/test/bugs/2">[#2]</a>', r.body)
+        assert_in('<a class="alink" href="/p/test/bugs/1/">[#1]</a>', r.body)
+        assert_in('<a class="alink strikethrough" href="/p/test/bugs/2/">[#2]</a>', r.body)
 
     def test_ticket_view_editable(self):
         summary = 'test ticket view page can be edited'
@@ -2381,7 +2381,7 @@ class TestFunctionalController(TrackerTestController):
             return_path, rcpts, body = _client.sendmail.call_args[0]
             body = body.split('\n')
             assert 'Subject: [test:bugs] #1 test <h2> ticket' in body
-            assert_in('<p><strong> <a class="alink" href="http://localhost:8080/p/test/bugs/1">[bugs:#1]</a> test &lt;h2&gt; ticket</strong></p>', body)
+            assert_in('<p><strong> <a class="alink" href="http://localhost:8080/p/test/bugs/1/">[bugs:#1]</a> test &lt;h2&gt; ticket</strong></p>', body)
 
     @patch('forgetracker.search.query_filter_choices')
     def test_multiselect(self, query_filter_choices):
@@ -3195,9 +3195,9 @@ class TestArtifactLinks(TrackerTestController):
         assert_equal(ticket_features.app.config._id, features.config._id)
 
         c.app = bugs
-        link = u'<div class="markdown_content"><p><a class="alink" href="/p/test/bugs/1">[#1]</a></p></div>'
+        link = u'<div class="markdown_content"><p><a class="alink" href="/p/test/bugs/1/">[#1]</a></p></div>'
         assert_equal(g.markdown.convert('[#1]'), link)
 
         c.app = features
-        link = u'<div class="markdown_content"><p><a class="alink" href="/p/test/features/1">[#1]</a></p></div>'
+        link = u'<div class="markdown_content"><p><a class="alink" href="/p/test/features/1/">[#1]</a></p></div>'
         assert_equal(g.markdown.convert('[#1]'), link)


[11/50] [abbrv] allura git commit: [#7897] ticket:828 Use SimpleMDE 1.4.0

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/49ef2414/Allura/allura/lib/widgets/resources/js/simplemde.min.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/simplemde.min.js b/Allura/allura/lib/widgets/resources/js/simplemde.min.js
index 1cef395..03fd926 100644
--- a/Allura/allura/lib/widgets/resources/js/simplemde.min.js
+++ b/Allura/allura/lib/widgets/resources/js/simplemde.min.js
@@ -1,13 +1,13 @@
 /*!
- * SimpleMDE v1.2.1 (https://github.com/NextStepWebs/simplemde-markdown-editor)
+ * SimpleMDE v1.4.0 (https://github.com/NextStepWebs/simplemde-markdown-editor)
  * Copyright Next Step Webs, Inc.
  * Licensed under the MIT license
  */
 
-function fixShortcut(e){return e=isMac?e.replace("Ctrl","Cmd"):e.replace("Cmd","Ctrl")}function createIcon(e,t){t=t||{};var n=document.createElement("a"),r=t.shortcut||shortcuts[e];return r&&(r=fixShortcut(r),n.title=r,n.title=n.title.replace("Cmd","⌘"),isMac&&(n.title=n.title.replace("Alt","⌥"))),n.className=t.className||"icon-"+e,n}function createSep(){return el=document.createElement("i"),el.className="separator",el.innerHTML="|",el}function getState(e,t){t=t||e.getCursor("start");var n=e.getTokenAt(t);if(!n.type)return{};for(var r,i,o=n.type.split(" "),l={},s=0;s<o.length;s++)r=o[s],"strong"===r?l.bold=!0:"variable-2"===r?(i=e.getLine(t.line),/^\s*\d+\.\s/.test(i)?l["ordered-list"]=!0:l["unordered-list"]=!0):"atom"===r?l.quote=!0:"em"===r?l.italic=!0:"quote"===r&&(l.quote=!0);return l}function toggleFullScreen(e){var t=e.codemirror.getWrapperElement(),n=document,r=n.fullScreen||n.mozFullScreen||n.webkitFullScreen,i=function(){t.requestFullScreen?t.requestFullScreen():t.mozRe
 questFullScreen?t.mozRequestFullScreen():t.webkitRequestFullScreen&&t.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)},o=function(){n.cancelFullScreen?n.cancelFullScreen():n.mozCancelFullScreen?n.mozCancelFullScreen():n.webkitCancelFullScreen&&n.webkitCancelFullScreen()};r?o&&o():i()}function toggleBold(e){_toggleBlock(e,"bold","**")}function toggleItalic(e){_toggleBlock(e,"italic","*")}function toggleCodeBlock(e){_toggleBlock(e,"code","```\r\n","\r\n```")}function toggleBlockquote(e){var t=e.codemirror;_toggleLine(t,"quote")}function toggleUnOrderedList(e){var t=e.codemirror;_toggleLine(t,"unordered-list")}function toggleOrderedList(e){var t=e.codemirror;_toggleLine(t,"ordered-list")}function drawLink(e){var t=e.codemirror,n=getState(t);_replaceSelection(t,n.link,"[","](http://)")}function drawImage(e){var t=e.codemirror,n=getState(t);_replaceSelection(t,n.image,"![](http://",")")}function undo(e){var t=e.codemirror;t.undo(),t.focus()}function redo(e){var t=e.codemirror;t.red
 o(),t.focus()}function togglePreview(e){var t=document.getElementsByClassName("editor-toolbar")[0],n=e.toolbar.preview,r=e.constructor.markdown,i=e.codemirror,o=i.getWrapperElement(),l=o.lastChild;/editor-preview/.test(l.className)||(l=document.createElement("div"),l.className="editor-preview",o.appendChild(l)),/editor-preview-active/.test(l.className)?(l.className=l.className.replace(/\s*editor-preview-active\s*/g,""),n.className=n.className.replace(/\s*active\s*/g,""),t.className=t.className.replace(/\s*disabled-for-preview\s*/g,"")):(setTimeout(function(){l.className+=" editor-preview-active"},1),n.className+=" active",t.className+=" disabled-for-preview");var s=i.getValue();l.innerHTML=r(s)}function _replaceSelection(e,t,n,r){if(!/editor-preview-active/.test(e.getWrapperElement().lastChild.className)){var i,o=e.getCursor("start"),l=e.getCursor("end");t?(i=e.getLine(o.line),n=i.slice(0,o.ch),r=i.slice(o.ch),e.replaceRange(n+r,{line:o.line,ch:0})):(i=e.getSelection(),e.replaceSele
 ction(n+i+r),o.ch+=n.length,l.ch+=n.length),e.setSelection(o,l),e.focus()}}function _toggleLine(e,t){if(!/editor-preview-active/.test(e.getWrapperElement().lastChild.className)){for(var n=getState(e),r=e.getCursor("start"),i=e.getCursor("end"),o={quote:/^(\s*)\>\s+/,"unordered-list":/^(\s*)(\*|\-|\+)\s+/,"ordered-list":/^(\s*)\d+\.\s+/},l={quote:"> ","unordered-list":"* ","ordered-list":"1. "},s=r.line;s<=i.line;s++)!function(r){var i=e.getLine(r);i=n[t]?i.replace(o[t],"$1"):l[t]+i,e.replaceRange(i,{line:r,ch:0},{line:r,ch:99999999999999})}(s);e.focus()}}function _toggleBlock(e,t,n,r){if(!/editor-preview-active/.test(e.codemirror.getWrapperElement().lastChild.className)){r="undefined"==typeof r?n:r;var i,o=e.codemirror,l=getState(o),s=n,a=r,u=o.getCursor("start"),c=o.getCursor("end");l[t]?(i=o.getLine(u.line),s=i.slice(0,u.ch),a=i.slice(u.ch),"bold"==t?(s=s.replace(/(\*\*|__)(?![\s\S]*(\*\*|__))/,""),a=a.replace(/(\*\*|__)/,"")):"italic"==t&&(s=s.replace(/(\*|_)(?![\s\S]*(\*|_))/,""
 ),a=a.replace(/(\*|_)/,"")),o.replaceRange(s+a,{line:u.line,ch:0},{line:u.line,ch:99999999999999}),"bold"==t?(u.ch-=2,c.ch-=2):"italic"==t&&(u.ch-=1,c.ch-=1)):(i=o.getSelection(),"bold"==t?(i=i.split("**").join(""),i=i.split("__").join("")):"italic"==t&&(i=i.split("*").join(""),i=i.split("_").join("")),o.replaceSelection(s+i+a),u.ch+=n.length,c.ch=u.ch+i.length),o.setSelection(u,c),o.focus()}}function wordCount(e){var t=/[a-zA-Z0-9_\u0392-\u03c9]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af]+/g,n=e.match(t),r=0;if(null===n)return r;for(var i=0;i<n.length;i++)r+=n[i].charCodeAt(0)>=19968?n[i].length:1;return r}function SimpleMDE(e){e=e||{},e.element&&(this.element=e.element),e.toolbar=e.toolbar===!1?!1:e.toolbar||SimpleMDE.toolbar,e.hasOwnProperty("status")||(e.status=["autosave","lines","words","cursor"]),this.options=e,this.render()}!function(e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else{if("function"==typeof define&&define.a
 md)return define([],e);this.CodeMirror=e()}}(function(){"use strict";function e(n,r){if(!(this instanceof e))return new e(n,r);this.options=r=r?Io(r):{},Io(Kl,r,!1),d(r);var i=r.value;"string"==typeof i&&(i=new ys(i,r.mode)),this.doc=i;var o=new e.inputStyles[r.inputStyle](this),l=this.display=new t(n,i,o);l.wrapper.CodeMirror=this,u(this),s(this),r.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),r.autofocus&&!Sl&&l.input.focus(),v(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,draggingText:!1,highlight:new To,keySeq:null,specialChars:null};var a=this;pl&&11>gl&&setTimeout(function(){a.display.input.reset(!0)},20),qn(this),Vo(),xn(this),this.curOp.forceUpdate=!0,Vi(this,i),r.autofocus&&!Sl||a.hasFocus()?setTimeout(Fo(pr,this),20):gr(this);for(var c in Xl)Xl.hasOwnProperty(c)&&Xl[c](this,r[c],Yl);C(this),r.finishInit&&r.finishInit(this);for(var h=0;h<es.length;++h)es[h
 ](this);Cn(this),ml&&r.lineWrapping&&"optimizelegibility"==getComputedStyle(l.lineDiv).textRendering&&(l.lineDiv.style.textRendering="auto")}function t(e,t,n){var r=this;this.input=n,r.scrollbarFiller=_o("div",null,"CodeMirror-scrollbar-filler"),r.scrollbarFiller.setAttribute("cm-not-content","true"),r.gutterFiller=_o("div",null,"CodeMirror-gutter-filler"),r.gutterFiller.setAttribute("cm-not-content","true"),r.lineDiv=_o("div",null,"CodeMirror-code"),r.selectionDiv=_o("div",null,null,"position: relative; z-index: 1"),r.cursorDiv=_o("div",null,"CodeMirror-cursors"),r.measure=_o("div",null,"CodeMirror-measure"),r.lineMeasure=_o("div",null,"CodeMirror-measure"),r.lineSpace=_o("div",[r.measure,r.lineMeasure,r.selectionDiv,r.cursorDiv,r.lineDiv],null,"position: relative; outline: none"),r.mover=_o("div",[_o("div",[r.lineSpace],"CodeMirror-lines")],null,"position: relative"),r.sizer=_o("div",[r.mover],"CodeMirror-sizer"),r.sizerWidth=null,r.heightForcer=_o("div",null,null,"position: absol
 ute; height: "+Ns+"px; width: 1px;"),r.gutters=_o("div",null,"CodeMirror-gutters"),r.lineGutter=null,r.scroller=_o("div",[r.sizer,r.heightForcer,r.gutters],"CodeMirror-scroll"),r.scroller.setAttribute("tabIndex","-1"),r.wrapper=_o("div",[r.scrollbarFiller,r.gutterFiller,r.scroller],"CodeMirror"),pl&&8>gl&&(r.gutters.style.zIndex=-1,r.scroller.style.paddingRight=0),ml||hl&&Sl||(r.scroller.draggable=!0),e&&(e.appendChild?e.appendChild(r.wrapper):e(r.wrapper)),r.viewFrom=r.viewTo=t.first,r.reportedViewFrom=r.reportedViewTo=t.first,r.view=[],r.renderedView=null,r.externalMeasured=null,r.viewOffset=0,r.lastWrapHeight=r.lastWrapWidth=0,r.updateLineNumbers=null,r.nativeBarWidth=r.barHeight=r.barWidth=0,r.scrollbarsClipped=!1,r.lineNumWidth=r.lineNumInnerWidth=r.lineNumChars=null,r.alignWidgets=!1,r.cachedCharWidth=r.cachedTextHeight=r.cachedPaddingH=null,r.maxLine=null,r.maxLineLength=0,r.maxLineChanged=!1,r.wheelDX=r.wheelDY=r.wheelStartX=r.wheelStartY=null,r.shift=!1,r.selForContextMenu=
 null,r.activeTouch=null,n.init(r)}function n(t){t.doc.mode=e.getMode(t.options,t.doc.modeOption),r(t)}function r(e){e.doc.iter(function(e){e.stateAfter&&(e.stateAfter=null),e.styles&&(e.styles=null)}),e.doc.frontier=e.doc.first,Pt(e,100),e.state.modeGen++,e.curOp&&In(e)}function i(e){e.options.lineWrapping?(Gs(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):(Us(e.display.wrapper,"CodeMirror-wrap"),f(e)),l(e),In(e),sn(e),setTimeout(function(){y(e)},100)}function o(e){var t=yn(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/bn(e.display)-3);return function(i){if(bi(e.doc,i))return 0;var o=0;if(i.widgets)for(var l=0;l<i.widgets.length;l++)i.widgets[l].height&&(o+=i.widgets[l].height);return n?o+(Math.ceil(i.text.length/r)||1)*t:o+t}}function l(e){var t=e.doc,n=o(e);t.iter(function(e){var t=n(e);t!=e.height&&Zi(e,t)})}function s(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s
 -\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),sn(e)}function a(e){u(e),In(e),setTimeout(function(){w(e)},20)}function u(e){var t=e.display.gutters,n=e.options.gutters;Ro(t);for(var r=0;r<n.length;++r){var i=n[r],o=t.appendChild(_o("div",null,"CodeMirror-gutter "+i));"CodeMirror-linenumbers"==i&&(e.display.lineGutter=o,o.style.width=(e.display.lineNumWidth||1)+"px")}t.style.display=r?"":"none",c(e)}function c(e){var t=e.display.gutters.offsetWidth;e.display.sizer.style.marginLeft=t+"px"}function h(e){if(0==e.height)return 0;for(var t,n=e.text.length,r=e;t=fi(r);){var i=t.find(0,!0);r=i.from.line,n+=i.from.ch-i.to.ch}for(r=e;t=di(r);){var i=t.find(0,!0);n-=r.text.length-i.from.ch,r=i.to.line,n+=r.text.length-i.to.ch}return n}function f(e){var t=e.display,n=e.doc;t.maxLine=Ki(n,n.first),t.maxLineLength=h(t.maxLine),t.maxLineChanged=!0,n.iter(function(e){var n=h(e);n>t.maxLineLength&&(t.maxLineLength=n,t.maxLine=e)})}function d(e){var t=Do(e.gutters,"CodeMirror-linenumbers")
 ;-1==t&&e.lineNumbers?e.gutters=e.gutters.concat(["CodeMirror-linenumbers"]):t>-1&&!e.lineNumbers&&(e.gutters=e.gutters.slice(0),e.gutters.splice(t,1))}function p(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+Ut(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+$t(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}function g(e,t,n){this.cm=n;var r=this.vert=_o("div",[_o("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=_o("div",[_o("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");e(r),e(i),Ss(r,"scroll",function(){r.clientHeight&&t(r.scrollTop,"vertical")}),Ss(i,"scroll",function(){i.clientWidth&&t(i.scrollLeft,"horizontal")}),this.checkedOverlay=!1,pl&&8>gl&&(this.horiz.style.minHeight=this.vert.style
 .minWidth="18px")}function m(){}function v(t){t.display.scrollbars&&(t.display.scrollbars.clear(),t.display.scrollbars.addClass&&Us(t.display.wrapper,t.display.scrollbars.addClass)),t.display.scrollbars=new e.scrollbarModel[t.options.scrollbarStyle](function(e){t.display.wrapper.insertBefore(e,t.display.scrollbarFiller),Ss(e,"mousedown",function(){t.state.focused&&setTimeout(function(){t.display.input.focus()},0)}),e.setAttribute("cm-not-content","true")},function(e,n){"horizontal"==n?nr(t,e):tr(t,e)},t),t.display.scrollbars.addClass&&Gs(t.display.wrapper,t.display.scrollbars.addClass)}function y(e,t){t||(t=p(e));var n=e.display.barWidth,r=e.display.barHeight;b(e,t);for(var i=0;4>i&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&D(e),b(e,p(e)),n=e.display.barWidth,r=e.display.barHeight}function b(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight
 =r.bottom)+"px",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}function x(e,t,n){var r=n&&null!=n.top?Math.max(0,n.top):e.scroller.scrollTop;r=Math.floor(r-qt(e));var i=n&&null!=n.bottom?n.bottom:r+e.wrapper.clientHeight,o=Ji(t,r),l=Ji(t,i);if(n&&n.ensure){var s=n.ensure.from.line,a=n.ensure.to.line;o>s?(o=s,l=Ji(t,eo(Ki(t,s))+e.wrapper.clientHeight)):Math.min(a,t.lastLine())>=l&&(o=Ji(t,eo(Ki(t,a))-e.wrapper.clientHeight),l=a)}return{from:o,to:Math.max(l,o+1)}}function w(e){var t=e.display,n=t.view;if(t.alignWidgets||t.gutters.firstChild&&e.options.fixedGutter){for(var r=S(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutte
 rs.offsetWidth,o=r+"px",l=0;l<n.length;l++)if(!n[l].hidden){e.options.fixedGutter&&n[l].gutter&&(n[l].gutter.style.left=o);var s=n[l].alignable;if(s)for(var a=0;a<s.length;a++)s[a].style.left=o}e.options.fixedGutter&&(t.gutters.style.left=r+i+"px")}}function C(e){if(!e.options.lineNumbers)return!1;var t=e.doc,n=k(e.options,t.first+t.size-1),r=e.display;if(n.length!=r.lineNumChars){var i=r.measure.appendChild(_o("div",[_o("div",n)],"CodeMirror-linenumber CodeMirror-gutter-elt")),o=i.firstChild.offsetWidth,l=i.offsetWidth-o;return r.lineGutter.style.width="",r.lineNumInnerWidth=Math.max(o,r.lineGutter.offsetWidth-l)+1,r.lineNumWidth=r.lineNumInnerWidth+l,r.lineNumChars=r.lineNumInnerWidth?n.length:-1,r.lineGutter.style.width=r.lineNumWidth+"px",c(e),!0}return!1}function k(e,t){return String(e.lineNumberFormatter(t+e.firstLineNumber))}function S(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function L(e,t,n){var r=e.display;this.viewport=t,this.
 visible=x(r,e.doc,t),this.editorIsHidden=!r.wrapper.offsetWidth,this.wrapperHeight=r.wrapper.clientHeight,this.wrapperWidth=r.wrapper.clientWidth,this.oldDisplayWidth=jt(e),this.force=n,this.dims=H(e),this.events=[]}function M(e){var t=e.display;!t.scrollbarsClipped&&t.scroller.offsetWidth&&(t.nativeBarWidth=t.scroller.offsetWidth-t.scroller.clientWidth,t.heightForcer.style.height=$t(e)+"px",t.sizer.style.marginBottom=-t.nativeBarWidth+"px",t.sizer.style.borderRightWidth=$t(e)+"px",t.scrollbarsClipped=!0)}function T(e,t){var n=e.display,r=e.doc;if(t.editorIsHidden)return zn(e),!1;if(!t.force&&t.visible.from>=n.viewFrom&&t.visible.to<=n.viewTo&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&0==Rn(e))return!1;C(e)&&(zn(e),t.dims=H(e));var i=r.first+r.size,o=Math.max(t.visible.from-e.options.viewportMargin,r.first),l=Math.min(i,t.visible.to+e.options.viewportMargin);n.viewFrom<o&&o-n.viewFrom<20&&(o=Math.max(r.first,n.viewFrom)),n.viewTo>l&&n.viewTo
 -l<20&&(l=Math.min(i,n.viewTo)),Dl&&(o=vi(e.doc,o),l=yi(e.doc,l));var s=o!=n.viewFrom||l!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;_n(e,o,l),n.viewOffset=eo(Ki(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var a=Rn(e);if(!s&&0==a&&!t.force&&n.renderedView==n.view&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo))return!1;var u=Uo();return a>4&&(n.lineDiv.style.display="none"),E(e,n.updateLineNumbers,t.dims),a>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,u&&Uo()!=u&&u.offsetHeight&&u.focus(),Ro(n.cursorDiv),Ro(n.selectionDiv),n.gutters.style.height=0,s&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,Pt(e,400)),n.updateLineNumbers=null,!0}function N(e,t){for(var n=t.viewport,r=!0;(r&&e.options.lineWrapping&&t.oldDisplayWidth!=jt(e)||(n&&null!=n.top&&(n={top:Math.min(e.doc.height+Ut(e.display)-Vt(e),n.top)}),t.visible=x(e.display,e.doc,n),!(t.visible.from>=e.display.viewFrom&&t.visible.to<=e.displ
 ay.viewTo)))&&T(e,t);r=!1){D(e);var i=p(e);Ht(e),O(e,i),y(e,i)}t.signal(e,"update",e),(e.display.viewFrom!=e.display.reportedViewFrom||e.display.viewTo!=e.display.reportedViewTo)&&(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function A(e,t){var n=new L(e,t);if(T(e,n)){D(e),N(e,n);var r=p(e);Ht(e),O(e,r),y(e,r),n.finish()}}function O(e,t){e.display.sizer.style.minHeight=t.docHeight+"px";var n=t.docHeight+e.display.barHeight;e.display.heightForcer.style.top=n+"px",e.display.gutters.style.height=Math.max(n+$t(e),t.clientHeight)+"px"}function D(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=0;r<t.view.length;r++){var i,o=t.view[r];if(!o.hidden){if(pl&&8>gl){var l=o.node.offsetTop+o.node.offsetHeight;i=l-n,n=l}else{var s=o.node.getBoundingClientRect();i=s.bottom-s.top}var a=o.line.height-i;if(2>i&&(i=yn(t)),(a>.001||-.001>a)&&(Zi(o.line,i),W(o.line),o.rest))for(var u=0;u<o.rest
 .length;u++)W(o.rest[u])}}}function W(e){if(e.widgets)for(var t=0;t<e.widgets.length;++t)e.widgets[t].height=e.widgets[t].node.offsetHeight}function H(e){for(var t=e.display,n={},r={},i=t.gutters.clientLeft,o=t.gutters.firstChild,l=0;o;o=o.nextSibling,++l)n[e.options.gutters[l]]=o.offsetLeft+o.clientLeft+i,r[e.options.gutters[l]]=o.clientWidth;return{fixedPos:S(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function E(e,t,n){function r(t){var n=t.nextSibling;return ml&&Ll&&e.display.currentWheelTarget==t?t.style.display="none":t.parentNode.removeChild(t),n}for(var i=e.display,o=e.options.lineNumbers,l=i.lineDiv,s=l.firstChild,a=i.view,u=i.viewFrom,c=0;c<a.length;c++){var h=a[c];if(h.hidden);else if(h.node&&h.node.parentNode==l){for(;s!=h.node;)s=r(s);var f=o&&null!=t&&u>=t&&h.lineNumber;h.changes&&(Do(h.changes,"gutter")>-1&&(f=!1),I(e,h,u,n)),f&&(Ro(h.lineNumber),h.lineNumber.appendChild(document.createTextNode(k(e.options,u
 )))),s=h.node.nextSibling}else{var d=U(e,h,u,n);l.insertBefore(d,s)}u+=h.size}for(;s;)s=r(s)}function I(e,t,n,r){for(var i=0;i<t.changes.length;i++){var o=t.changes[i];"text"==o?B(e,t):"gutter"==o?R(e,t,n,r):"class"==o?_(t):"widget"==o&&q(e,t,r)}t.changes=null}function F(e){return e.node==e.text&&(e.node=_o("div",null,null,"position: relative"),e.text.parentNode&&e.text.parentNode.replaceChild(e.node,e.text),e.node.appendChild(e.text),pl&&8>gl&&(e.node.style.zIndex=2)),e.node}function z(e){var t=e.bgClass?e.bgClass+" "+(e.line.bgClass||""):e.line.bgClass;if(t&&(t+=" CodeMirror-linebackground"),e.background)t?e.background.className=t:(e.background.parentNode.removeChild(e.background),e.background=null);else if(t){var n=F(e);e.background=n.insertBefore(_o("div",null,t),n.firstChild)}}function P(e,t){var n=e.display.externalMeasured;return n&&n.line==t.line?(e.display.externalMeasured=null,t.measure=n.measure,n.built):Ii(e,t)}function B(e,t){var n=t.text.className,r=P(e,t);t.text==t.no
 de&&(t.node=r.pre),t.text.parentNode.replaceChild(r.pre,t.text),t.text=r.pre,r.bgClass!=t.bgClass||r.textClass!=t.textClass?(t.bgClass=r.bgClass,t.textClass=r.textClass,_(t)):n&&(t.text.className=n)}function _(e){z(e),e.line.wrapClass?F(e).className=e.line.wrapClass:e.node!=e.text&&(e.node.className="");var t=e.textClass?e.textClass+" "+(e.line.textClass||""):e.line.textClass;e.text.className=t||""}function R(e,t,n,r){t.gutter&&(t.node.removeChild(t.gutter),t.gutter=null);var i=t.line.gutterMarkers;if(e.options.lineNumbers||i){var o=F(t),l=t.gutter=_o("div",null,"CodeMirror-gutter-wrapper","left: "+(e.options.fixedGutter?r.fixedPos:-r.gutterTotalWidth)+"px; width: "+r.gutterTotalWidth+"px");if(e.display.input.setUneditable(l),o.insertBefore(l,t.text),t.line.gutterClass&&(l.className+=" "+t.line.gutterClass),!e.options.lineNumbers||i&&i["CodeMirror-linenumbers"]||(t.lineNumber=l.appendChild(_o("div",k(e.options,n),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+r.gutterLeft["C
 odeMirror-linenumbers"]+"px; width: "+e.display.lineNumInnerWidth+"px"))),i)for(var s=0;s<e.options.gutters.length;++s){var a=e.options.gutters[s],u=i.hasOwnProperty(a)&&i[a];u&&l.appendChild(_o("div",[u],"CodeMirror-gutter-elt","left: "+r.gutterLeft[a]+"px; width: "+r.gutterWidth[a]+"px"))}}}function q(e,t,n){t.alignable&&(t.alignable=null);for(var r,i=t.node.firstChild;i;i=r){var r=i.nextSibling;"CodeMirror-linewidget"==i.className&&t.node.removeChild(i)}G(e,t,n)}function U(e,t,n,r){var i=P(e,t);return t.text=t.node=i.pre,i.bgClass&&(t.bgClass=i.bgClass),i.textClass&&(t.textClass=i.textClass),_(t),R(e,t,n,r),G(e,t,r),t.node}function G(e,t,n){if($(e,t.line,t,n,!0),t.rest)for(var r=0;r<t.rest.length;r++)$(e,t.rest[r],t,n,!1)}function $(e,t,n,r,i){if(t.widgets)for(var o=F(n),l=0,s=t.widgets;l<s.length;++l){var a=s[l],u=_o("div",[a.node],"CodeMirror-linewidget");a.handleMouseEvents||u.setAttribute("cm-ignore-events","true"),j(a,u,n,r),e.display.input.setUneditable(u),i&&a.above?o.inse
 rtBefore(u,n.gutter||n.text):o.appendChild(u),wo(a,"redraw")}}function j(e,t,n,r){if(e.noHScroll){(n.alignable||(n.alignable=[])).push(t);var i=r.wrapperWidth;t.style.left=r.fixedPos+"px",e.coverGutter||(i-=r.gutterTotalWidth,t.style.paddingLeft=r.gutterTotalWidth+"px"),t.style.width=i+"px"}e.coverGutter&&(t.style.zIndex=5,t.style.position="relative",e.noHScroll||(t.style.marginLeft=-r.gutterTotalWidth+"px"))}function V(e){return Wl(e.line,e.ch)}function K(e,t){return Hl(e,t)<0?t:e}function X(e,t){return Hl(e,t)<0?e:t}function Y(e){e.state.focused||(e.display.input.focus(),pr(e))}function Z(e){return e.options.readOnly||e.doc.cantEdit}function Q(e,t,n,r,i){var o=e.doc;e.display.shift=!1,r||(r=o.sel);var l=e.state.pasteIncoming||"paste"==i,s=Vs(t),a=null;l&&r.ranges.length>1&&(El&&El.join("\n")==t?a=r.ranges.length%El.length==0&&Wo(El,Vs):s.length==r.ranges.length&&(a=Wo(s,function(e){return[e]})));for(var u=r.ranges.length-1;u>=0;u--){var c=r.ranges[u],h=c.from(),f=c.to();c.empty()&
 &(n&&n>0?h=Wl(h.line,h.ch-n):e.state.overwrite&&!l&&(f=Wl(f.line,Math.min(Ki(o,f.line).text.length,f.ch+Oo(s).length))));var d=e.curOp.updateInput,p={from:h,to:f,text:a?a[u%a.length]:s,origin:i||(l?"paste":e.state.cutIncoming?"cut":"+input")};kr(e.doc,p),wo(e,"inputRead",e,p)}t&&!l&&et(e,t),Ir(e),e.curOp.updateInput=d,e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=!1}function J(e,t){var n=e.clipboardData&&e.clipboardData.getData("text/plain");return n?(e.preventDefault(),An(t,function(){Q(t,n,0,null,"paste")}),!0):void 0}function et(e,t){if(e.options.electricChars&&e.options.smartIndent)for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var i=n.ranges[r];if(!(i.head.ch>100||r&&n.ranges[r-1].head.line==i.head.line)){var o=e.getModeAt(i.head),l=!1;if(o.electricChars){for(var s=0;s<o.electricChars.length;s++)if(t.indexOf(o.electricChars.charAt(s))>-1){l=zr(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(Ki(e.doc,i.head.line).text.slice(0,i.head.ch))
 &&(l=zr(e,i.head.line,"smart"));l&&wo(e,"electricInput",e,i.head.line)}}}function tt(e){for(var t=[],n=[],r=0;r<e.doc.sel.ranges.length;r++){var i=e.doc.sel.ranges[r].head.line,o={anchor:Wl(i,0),head:Wl(i+1,0)};n.push(o),t.push(e.getRange(o.anchor,o.head))}return{text:t,ranges:n}}function nt(e){e.setAttribute("autocorrect","off"),e.setAttribute("autocapitalize","off"),e.setAttribute("spellcheck","false")}function rt(e){this.cm=e,this.prevInput="",this.pollingFast=!1,this.polling=new To,this.inaccurateSelection=!1,this.hasSelection=!1,this.composing=null}function it(){var e=_o("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em; outline: none"),t=_o("div",[e],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");return ml?e.style.width="1000px":e.setAttribute("wrap","off"),kl&&(e.style.border="1px solid black"),nt(e),t}function ot(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling
 =new To,this.gracePeriod=!1}function lt(e,t){var n=Qt(e,t.line);if(!n||n.hidden)return null;var r=Ki(e.doc,t.line),i=Xt(n,r,t.line),o=to(r),l="left";if(o){var s=sl(o,t.ch);l=s%2?"right":"left"}var a=tn(i.map,t.ch,l);return a.offset="right"==a.collapse?a.end:a.start,a}function st(e,t){return t&&(e.bad=!0),e}function at(e,t,n){var r;if(t==e.display.lineDiv){if(r=e.display.lineDiv.childNodes[n],!r)return st(e.clipPos(Wl(e.display.viewTo-1)),!0);t=null,n=0}else for(r=t;;r=r.parentNode){if(!r||r==e.display.lineDiv)return null;if(r.parentNode&&r.parentNode==e.display.lineDiv)break}for(var i=0;i<e.display.view.length;i++){var o=e.display.view[i];if(o.node==r)return ut(o,t,n)}}function ut(e,t,n){function r(t,n,r){for(var i=-1;i<(c?c.length:0);i++)for(var o=0>i?u.map:c[i],l=0;l<o.length;l+=3){var s=o[l+2];if(s==t||s==n){var a=Qi(0>i?e.line:e.rest[i]),h=o[l]+r;return(0>r||s!=t)&&(h=o[l+(r?1:0)]),Wl(a,h)}}}var i=e.text.firstChild,o=!1;if(!t||!_s(i,t))return st(Wl(Qi(e.line),0),!0);if(t==i&&(o=
 !0,t=i.childNodes[n],n=0,!t)){var l=e.rest?Oo(e.rest):e.line;return st(Wl(Qi(l),l.text.length),o)}var s=3==t.nodeType?t:null,a=t;for(s||1!=t.childNodes.length||3!=t.firstChild.nodeType||(s=t.firstChild,n&&(n=s.nodeValue.length));a.parentNode!=i;)a=a.parentNode;var u=e.measure,c=u.maps,h=r(s,a,n);if(h)return st(h,o);for(var f=a.nextSibling,d=s?s.nodeValue.length-n:0;f;f=f.nextSibling){if(h=r(f,f.firstChild,0))return st(Wl(h.line,h.ch-d),o);d+=f.textContent.length}for(var p=a.previousSibling,d=n;p;p=p.previousSibling){if(h=r(p,p.firstChild,-1))return st(Wl(h.line,h.ch+d),o);d+=f.textContent.length}}function ct(e,t,n,r,i){function o(e){return function(t){return t.id==e}}function l(t){if(1==t.nodeType){var n=t.getAttribute("cm-text");if(null!=n)return""==n&&(n=t.textContent.replace(/\u200b/g,"")),void(s+=n);var u,c=t.getAttribute("cm-marker");if(c){var h=e.findMarks(Wl(r,0),Wl(i+1,0),o(+c));return void(h.length&&(u=h[0].find())&&(s+=Xi(e.doc,u.from,u.to).join("\n")))}if("false"==t.getAt
 tribute("contenteditable"))return;for(var f=0;f<t.childNodes.length;f++)l(t.childNodes[f]);/^(pre|div|p)$/i.test(t.nodeName)&&(a=!0)}else if(3==t.nodeType){var d=t.nodeValue;if(!d)return;a&&(s+="\n",a=!1),s+=d}}for(var s="",a=!1;l(t),t!=n;)t=t.nextSibling;return s}function ht(e,t){this.ranges=e,this.primIndex=t}function ft(e,t){this.anchor=e,this.head=t}function dt(e,t){var n=e[t];e.sort(function(e,t){return Hl(e.from(),t.from())}),t=Do(e,n);for(var r=1;r<e.length;r++){var i=e[r],o=e[r-1];if(Hl(o.to(),i.from())>=0){var l=X(o.from(),i.from()),s=K(o.to(),i.to()),a=o.empty()?i.from()==i.head:o.from()==o.head;t>=r&&--t,e.splice(--r,2,new ft(a?s:l,a?l:s))}}return new ht(e,t)}function pt(e,t){return new ht([new ft(e,t||e)],0)}function gt(e,t){return Math.max(e.first,Math.min(t,e.first+e.size-1))}function mt(e,t){if(t.line<e.first)return Wl(e.first,0);var n=e.first+e.size-1;return t.line>n?Wl(n,Ki(e,n).text.length):vt(t,Ki(e,t.line).text.length)}function vt(e,t){var n=e.ch;return null==n||
 n>t?Wl(e.line,t):0>n?Wl(e.line,0):e}function yt(e,t){return t>=e.first&&t<e.first+e.size}function bt(e,t){for(var n=[],r=0;r<t.length;r++)n[r]=mt(e,t[r]);return n}function xt(e,t,n,r){if(e.cm&&e.cm.display.shift||e.extend){var i=t.anchor;if(r){var o=Hl(n,i)<0;o!=Hl(r,i)<0?(i=n,n=r):o!=Hl(n,r)<0&&(n=r)}return new ft(i,n)}return new ft(r||n,n)}function wt(e,t,n,r){Tt(e,new ht([xt(e,e.sel.primary(),t,n)],0),r)}function Ct(e,t,n){for(var r=[],i=0;i<e.sel.ranges.length;i++)r[i]=xt(e,e.sel.ranges[i],t[i],null);var o=dt(r,e.sel.primIndex);Tt(e,o,n)}function kt(e,t,n,r){var i=e.sel.ranges.slice(0);i[t]=n,Tt(e,dt(i,e.sel.primIndex),r)}function St(e,t,n,r){Tt(e,pt(t,n),r)}function Lt(e,t){var n={ranges:t.ranges,update:function(t){this.ranges=[];for(var n=0;n<t.length;n++)this.ranges[n]=new ft(mt(e,t[n].anchor),mt(e,t[n].head))}};return Ms(e,"beforeSelectionChange",e,n),e.cm&&Ms(e.cm,"beforeSelectionChange",e.cm,n),n.ranges!=t.ranges?dt(n.ranges,n.ranges.length-1):t}function Mt(e,t,n){var r=e.
 history.done,i=Oo(r);i&&i.ranges?(r[r.length-1]=t,Nt(e,t,n)):Tt(e,t,n)}function Tt(e,t,n){Nt(e,t,n),ao(e,e.sel,e.cm?e.cm.curOp.id:0/0,n)}function Nt(e,t,n){(Lo(e,"beforeSelectionChange")||e.cm&&Lo(e.cm,"beforeSelectionChange"))&&(t=Lt(e,t));var r=n&&n.bias||(Hl(t.primary().head,e.sel.primary().head)<0?-1:1);At(e,Dt(e,t,r,!0)),n&&n.scroll===!1||!e.cm||Ir(e.cm)}function At(e,t){t.equals(e.sel)||(e.sel=t,e.cm&&(e.cm.curOp.updateInput=e.cm.curOp.selectionChanged=!0,So(e.cm)),wo(e,"cursorActivity",e))}function Ot(e){At(e,Dt(e,e.sel,null,!1),Os)}function Dt(e,t,n,r){for(var i,o=0;o<t.ranges.length;o++){var l=t.ranges[o],s=Wt(e,l.anchor,n,r),a=Wt(e,l.head,n,r);(i||s!=l.anchor||a!=l.head)&&(i||(i=t.ranges.slice(0,o)),i[o]=new ft(s,a))}return i?dt(i,t.primIndex):t}function Wt(e,t,n,r){var i=!1,o=t,l=n||1;e.cantEdit=!1;e:for(;;){var s=Ki(e,o.line);if(s.markedSpans)for(var a=0;a<s.markedSpans.length;++a){var u=s.markedSpans[a],c=u.marker;if((null==u.from||(c.inclusiveLeft?u.from<=o.ch:u.from<o
 .ch))&&(null==u.to||(c.inclusiveRight?u.to>=o.ch:u.to>o.ch))){if(r&&(Ms(c,"beforeCursorEnter"),c.explicitlyCleared)){if(s.markedSpans){--a;continue}break}if(!c.atomic)continue;var h=c.find(0>l?-1:1);if(0==Hl(h,o)&&(h.ch+=l,h.ch<0?h=h.line>e.first?mt(e,Wl(h.line-1)):null:h.ch>s.text.length&&(h=h.line<e.first+e.size-1?Wl(h.line+1,0):null),!h)){if(i)return r?(e.cantEdit=!0,Wl(e.first,0)):Wt(e,t,n,!0);i=!0,h=t,l=-l}o=h;continue e}}return o}}function Ht(e){e.display.input.showSelection(e.display.input.prepareSelection())}function Et(e,t){for(var n=e.doc,r={},i=r.cursors=document.createDocumentFragment(),o=r.selection=document.createDocumentFragment(),l=0;l<n.sel.ranges.length;l++)if(t!==!1||l!=n.sel.primIndex){var s=n.sel.ranges[l],a=s.empty();(a||e.options.showCursorWhenSelecting)&&It(e,s,i),a||Ft(e,s,o)}return r}function It(e,t,n){var r=dn(e,t.head,"div",null,null,!e.options.singleCursorHeightPerLine),i=n.appendChild(_o("div"," ","CodeMirror-cursor"));if(i.style.left=r.left+"px",i.sty
 le.top=r.top+"px",i.style.height=Math.max(0,r.bottom-r.top)*e.options.cursorHeight+"px",r.other){var o=n.appendChild(_o("div"," ","CodeMirror-cursor CodeMirror-secondarycursor"));o.style.display="",o.style.left=r.other.left+"px",o.style.top=r.other.top+"px",o.style.height=.85*(r.other.bottom-r.other.top)+"px"}}function Ft(e,t,n){function r(e,t,n,r){0>t&&(t=0),t=Math.round(t),r=Math.round(r),s.appendChild(_o("div",null,"CodeMirror-selected","position: absolute; left: "+e+"px; top: "+t+"px; width: "+(null==n?c-e:n)+"px; height: "+(r-t)+"px"))}function i(t,n,i){function o(n,r){return fn(e,Wl(t,n),"div",h,r)}var s,a,h=Ki(l,t),f=h.text.length;return Qo(to(h),n||0,null==i?f:i,function(e,t,l){var h,d,p,g=o(e,"left");if(e==t)h=g,d=p=g.left;else{if(h=o(t-1,"right"),"rtl"==l){var m=g;g=h,h=m}d=g.left,p=h.right}null==n&&0==e&&(d=u),h.top-g.top>3&&(r(d,g.top,null,g.bottom),d=u,g.bottom<h.top&&r(d,g.bottom,null,h.top)),null==i&&t==f&&(p=c),(!s||g.top<s.top||g.top==s.top&&g.left<s.left)&&(s=g),(
 !a||h.bottom>a.bottom||h.bottom==a.bottom&&h.right>a.right)&&(a=h),u+1>d&&(d=u),r(d,h.top,p-d,h.bottom)}),{start:s,end:a}}var o=e.display,l=e.doc,s=document.createDocumentFragment(),a=Gt(e.display),u=a.left,c=Math.max(o.sizerWidth,jt(e)-o.sizer.offsetLeft)-a.right,h=t.from(),f=t.to();if(h.line==f.line)i(h.line,h.ch,f.ch);else{var d=Ki(l,h.line),p=Ki(l,f.line),g=gi(d)==gi(p),m=i(h.line,h.ch,g?d.text.length+1:null).end,v=i(f.line,g?0:null,f.ch).start;g&&(m.top<v.top-2?(r(m.right,m.top,null,m.bottom),r(u,v.top,v.left,v.bottom)):r(m.right,m.top,v.left-m.right,m.bottom)),m.bottom<v.top&&r(u,m.bottom,null,v.top)}n.appendChild(s)}function zt(e){if(e.state.focused){var t=e.display;clearInterval(t.blinker);var n=!0;t.cursorDiv.style.visibility="",e.options.cursorBlinkRate>0?t.blinker=setInterval(function(){t.cursorDiv.style.visibility=(n=!n)?"":"hidden"},e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function Pt(e,t){e.doc.mode.startState&&e.
 doc.frontier<e.display.viewTo&&e.state.highlight.set(t,Fo(Bt,e))}function Bt(e){var t=e.doc;if(t.frontier<t.first&&(t.frontier=t.first),!(t.frontier>=e.display.viewTo)){var n=+new Date+e.options.workTime,r=ns(t.mode,Rt(e,t.frontier)),i=[];
-t.iter(t.frontier,Math.min(t.first+t.size,e.display.viewTo+500),function(o){if(t.frontier>=e.display.viewFrom){var l=o.styles,s=Di(e,o,r,!0);o.styles=s.styles;var a=o.styleClasses,u=s.classes;u?o.styleClasses=u:a&&(o.styleClasses=null);for(var c=!l||l.length!=o.styles.length||a!=u&&(!a||!u||a.bgClass!=u.bgClass||a.textClass!=u.textClass),h=0;!c&&h<l.length;++h)c=l[h]!=o.styles[h];c&&i.push(t.frontier),o.stateAfter=ns(t.mode,r)}else Hi(e,o.text,r),o.stateAfter=t.frontier%5==0?ns(t.mode,r):null;return++t.frontier,+new Date>n?(Pt(e,e.options.workDelay),!0):void 0}),i.length&&An(e,function(){for(var t=0;t<i.length;t++)Fn(e,i[t],"text")})}}function _t(e,t,n){for(var r,i,o=e.doc,l=n?-1:t-(e.doc.mode.innerMode?1e3:100),s=t;s>l;--s){if(s<=o.first)return o.first;var a=Ki(o,s-1);if(a.stateAfter&&(!n||s<=o.frontier))return s;var u=Hs(a.text,null,e.options.tabSize);(null==i||r>u)&&(i=s-1,r=u)}return i}function Rt(e,t,n){var r=e.doc,i=e.display;if(!r.mode.startState)return!0;var o=_t(e,t,n),l=o>
 r.first&&Ki(r,o-1).stateAfter;return l=l?ns(r.mode,l):rs(r.mode),r.iter(o,t,function(n){Hi(e,n.text,l);var s=o==t-1||o%5==0||o>=i.viewFrom&&o<i.viewTo;n.stateAfter=s?ns(r.mode,l):null,++o}),n&&(r.frontier=o),l}function qt(e){return e.lineSpace.offsetTop}function Ut(e){return e.mover.offsetHeight-e.lineSpace.offsetHeight}function Gt(e){if(e.cachedPaddingH)return e.cachedPaddingH;var t=qo(e.measure,_o("pre","x")),n=window.getComputedStyle?window.getComputedStyle(t):t.currentStyle,r={left:parseInt(n.paddingLeft),right:parseInt(n.paddingRight)};return isNaN(r.left)||isNaN(r.right)||(e.cachedPaddingH=r),r}function $t(e){return Ns-e.display.nativeBarWidth}function jt(e){return e.display.scroller.clientWidth-$t(e)-e.display.barWidth}function Vt(e){return e.display.scroller.clientHeight-$t(e)-e.display.barHeight}function Kt(e,t,n){var r=e.options.lineWrapping,i=r&&jt(e);if(!t.measure.heights||r&&t.measure.width!=i){var o=t.measure.heights=[];if(r){t.measure.width=i;for(var l=t.text.firstChi
 ld.getClientRects(),s=0;s<l.length-1;s++){var a=l[s],u=l[s+1];Math.abs(a.bottom-u.bottom)>2&&o.push((a.bottom+u.top)/2-n.top)}}o.push(n.bottom-n.top)}}function Xt(e,t,n){if(e.line==t)return{map:e.measure.map,cache:e.measure.cache};for(var r=0;r<e.rest.length;r++)if(e.rest[r]==t)return{map:e.measure.maps[r],cache:e.measure.caches[r]};for(var r=0;r<e.rest.length;r++)if(Qi(e.rest[r])>n)return{map:e.measure.maps[r],cache:e.measure.caches[r],before:!0}}function Yt(e,t){t=gi(t);var n=Qi(t),r=e.display.externalMeasured=new Hn(e.doc,t,n);r.lineN=n;var i=r.built=Ii(e,r);return r.text=i.pre,qo(e.display.lineMeasure,i.pre),r}function Zt(e,t,n,r){return en(e,Jt(e,t),n,r)}function Qt(e,t){if(t>=e.display.viewFrom&&t<e.display.viewTo)return e.display.view[Pn(e,t)];var n=e.display.externalMeasured;return n&&t>=n.lineN&&t<n.lineN+n.size?n:void 0}function Jt(e,t){var n=Qi(t),r=Qt(e,n);r&&!r.text?r=null:r&&r.changes&&I(e,r,n,H(e)),r||(r=Yt(e,t));var i=Xt(r,t,n);return{line:t,view:r,rect:null,map:i.ma
 p,cache:i.cache,before:i.before,hasHeights:!1}}function en(e,t,n,r,i){t.before&&(n=-1);var o,l=n+(r||"");return t.cache.hasOwnProperty(l)?o=t.cache[l]:(t.rect||(t.rect=t.view.text.getBoundingClientRect()),t.hasHeights||(Kt(e,t.view,t.rect),t.hasHeights=!0),o=nn(e,t,n,r),o.bogus||(t.cache[l]=o)),{left:o.left,right:o.right,top:i?o.rtop:o.top,bottom:i?o.rbottom:o.bottom}}function tn(e,t,n){for(var r,i,o,l,s=0;s<e.length;s+=3){var a=e[s],u=e[s+1];if(a>t?(i=0,o=1,l="left"):u>t?(i=t-a,o=i+1):(s==e.length-3||t==u&&e[s+3]>t)&&(o=u-a,i=o-1,t>=u&&(l="right")),null!=i){if(r=e[s+2],a==u&&n==(r.insertLeft?"left":"right")&&(l=n),"left"==n&&0==i)for(;s&&e[s-2]==e[s-3]&&e[s-1].insertLeft;)r=e[(s-=3)+2],l="left";if("right"==n&&i==u-a)for(;s<e.length-3&&e[s+3]==e[s+4]&&!e[s+5].insertLeft;)r=e[(s+=3)+2],l="right";break}}return{node:r,start:i,end:o,collapse:l,coverStart:a,coverEnd:u}}function nn(e,t,n,r){var i,o=tn(t.map,n,r),l=o.node,s=o.start,a=o.end,u=o.collapse;if(3==l.nodeType){for(var c=0;4>c;c++
 ){for(;s&&Bo(t.line.text.charAt(o.coverStart+s));)--s;for(;o.coverStart+a<o.coverEnd&&Bo(t.line.text.charAt(o.coverStart+a));)++a;if(pl&&9>gl&&0==s&&a==o.coverEnd-o.coverStart)i=l.parentNode.getBoundingClientRect();else if(pl&&e.options.lineWrapping){var h=Fs(l,s,a).getClientRects();i=h.length?h["right"==r?h.length-1:0]:Pl}else i=Fs(l,s,a).getBoundingClientRect()||Pl;if(i.left||i.right||0==s)break;a=s,s-=1,u="right"}pl&&11>gl&&(i=rn(e.display.measure,i))}else{s>0&&(u=r="right");var h;i=e.options.lineWrapping&&(h=l.getClientRects()).length>1?h["right"==r?h.length-1:0]:l.getBoundingClientRect()}if(pl&&9>gl&&!s&&(!i||!i.left&&!i.right)){var f=l.parentNode.getClientRects()[0];i=f?{left:f.left,right:f.left+bn(e.display),top:f.top,bottom:f.bottom}:Pl}for(var d=i.top-t.rect.top,p=i.bottom-t.rect.top,g=(d+p)/2,m=t.view.measure.heights,c=0;c<m.length-1&&!(g<m[c]);c++);var v=c?m[c-1]:0,y=m[c],b={left:("right"==u?i.right:i.left)-t.rect.left,right:("left"==u?i.left:i.right)-t.rect.left,top:v,bo
 ttom:y};return i.left||i.right||(b.bogus=!0),e.options.singleCursorHeightPerLine||(b.rtop=d,b.rbottom=p),b}function rn(e,t){if(!window.screen||null==screen.logicalXDPI||screen.logicalXDPI==screen.deviceXDPI||!Zo(e))return t;var n=screen.logicalXDPI/screen.deviceXDPI,r=screen.logicalYDPI/screen.deviceYDPI;return{left:t.left*n,right:t.right*n,top:t.top*r,bottom:t.bottom*r}}function on(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,e.rest))for(var t=0;t<e.rest.length;t++)e.measure.caches[t]={}}function ln(e){e.display.externalMeasure=null,Ro(e.display.lineMeasure);for(var t=0;t<e.display.view.length;t++)on(e.display.view[t])}function sn(e){ln(e),e.display.cachedCharWidth=e.display.cachedTextHeight=e.display.cachedPaddingH=null,e.options.lineWrapping||(e.display.maxLineChanged=!0),e.display.lineNumChars=null}function an(){return window.pageXOffset||(document.documentElement||document.body).scrollLeft}function un(){return window.pageYOffset||(document.documentElement||docume
 nt.body).scrollTop}function cn(e,t,n,r){if(t.widgets)for(var i=0;i<t.widgets.length;++i)if(t.widgets[i].above){var o=Ci(t.widgets[i]);n.top+=o,n.bottom+=o}if("line"==r)return n;r||(r="local");var l=eo(t);if("local"==r?l+=qt(e.display):l-=e.display.viewOffset,"page"==r||"window"==r){var s=e.display.lineSpace.getBoundingClientRect();l+=s.top+("window"==r?0:un());var a=s.left+("window"==r?0:an());n.left+=a,n.right+=a}return n.top+=l,n.bottom+=l,n}function hn(e,t,n){if("div"==n)return t;var r=t.left,i=t.top;if("page"==n)r-=an(),i-=un();else if("local"==n||!n){var o=e.display.sizer.getBoundingClientRect();r+=o.left,i+=o.top}var l=e.display.lineSpace.getBoundingClientRect();return{left:r-l.left,top:i-l.top}}function fn(e,t,n,r,i){return r||(r=Ki(e.doc,t.line)),cn(e,r,Zt(e,r,t.ch,i),n)}function dn(e,t,n,r,i,o){function l(t,l){var s=en(e,i,t,l?"right":"left",o);return l?s.left=s.right:s.right=s.left,cn(e,r,s,n)}function s(e,t){var n=a[t],r=n.level%2;return e==Jo(n)&&t&&n.level<a[t-1].level?
 (n=a[--t],e=el(n)-(n.level%2?0:1),r=!0):e==el(n)&&t<a.length-1&&n.level<a[t+1].level&&(n=a[++t],e=Jo(n)-n.level%2,r=!1),r&&e==n.to&&e>n.from?l(e-1):l(e,r)}r=r||Ki(e.doc,t.line),i||(i=Jt(e,r));var a=to(r),u=t.ch;if(!a)return l(u);var c=sl(a,u),h=s(u,c);return null!=Qs&&(h.other=s(u,Qs)),h}function pn(e,t){var n=0,t=mt(e.doc,t);e.options.lineWrapping||(n=bn(e.display)*t.ch);var r=Ki(e.doc,t.line),i=eo(r)+qt(e.display);return{left:n,right:n,top:i,bottom:i+r.height}}function gn(e,t,n,r){var i=Wl(e,t);return i.xRel=r,n&&(i.outside=!0),i}function mn(e,t,n){var r=e.doc;if(n+=e.display.viewOffset,0>n)return gn(r.first,0,!0,-1);var i=Ji(r,n),o=r.first+r.size-1;if(i>o)return gn(r.first+r.size-1,Ki(r,o).text.length,!0,1);0>t&&(t=0);for(var l=Ki(r,i);;){var s=vn(e,l,i,t,n),a=di(l),u=a&&a.find(0,!0);if(!a||!(s.ch>u.from.ch||s.ch==u.from.ch&&s.xRel>0))return s;i=Qi(l=u.to.line)}}function vn(e,t,n,r,i){function o(r){var i=dn(e,Wl(n,r),"line",t,u);return s=!0,l>i.bottom?i.left-a:l<i.top?i.left+a:(s
 =!1,i.left)}var l=i-eo(t),s=!1,a=2*e.display.wrapper.clientWidth,u=Jt(e,t),c=to(t),h=t.text.length,f=tl(t),d=nl(t),p=o(f),g=s,m=o(d),v=s;if(r>m)return gn(n,d,v,1);for(;;){if(c?d==f||d==ul(t,f,1):1>=d-f){for(var y=p>r||m-r>=r-p?f:d,b=r-(y==f?p:m);Bo(t.text.charAt(y));)++y;var x=gn(n,y,y==f?g:v,-1>b?-1:b>1?1:0);return x}var w=Math.ceil(h/2),C=f+w;if(c){C=f;for(var k=0;w>k;++k)C=ul(t,C,1)}var S=o(C);S>r?(d=C,m=S,(v=s)&&(m+=1e3),h=w):(f=C,p=S,g=s,h-=w)}}function yn(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(null==Il){Il=_o("pre");for(var t=0;49>t;++t)Il.appendChild(document.createTextNode("x")),Il.appendChild(_o("br"));Il.appendChild(document.createTextNode("x"))}qo(e.measure,Il);var n=Il.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),Ro(e.measure),n||1}function bn(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t=_o("span","xxxxxxxxxx"),n=_o("pre",[t]);qo(e.measure,n);var r=t.getBoundingClientRect(),i=(r.right-r.left)/10;return i>2&&(e.cachedCharWidth=i)
 ,i||10}function xn(e){e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++_l},Bl?Bl.ops.push(e.curOp):e.curOp.ownsGroup=Bl={ops:[e.curOp],delayedCallbacks:[]}}function wn(e){var t=e.delayedCallbacks,n=0;do{for(;n<t.length;n++)t[n]();for(var r=0;r<e.ops.length;r++){var i=e.ops[r];if(i.cursorActivityHandlers)for(;i.cursorActivityCalled<i.cursorActivityHandlers.length;)i.cursorActivityHandlers[i.cursorActivityCalled++](i.cm)}}while(n<t.length)}function Cn(e){var t=e.curOp,n=t.ownsGroup;if(n)try{wn(n)}finally{Bl=null;for(var r=0;r<n.ops.length;r++)n.ops[r].cm.curOp=null;kn(n)}}function kn(e){for(var t=e.ops,n=0;n<t.length;n++)Sn(t[n]);for(var n=0;n<t.length;n++)Ln(t[n]);for(var n=0;n<t.length;n++)Mn(t[n]);for(var n=0;n<t.length;n++)Tn(t[n]);for(var n=0;n<t.length;n++)Nn(t[n])}func
 tion Sn(e){var t=e.cm,n=t.display;M(t),e.updateMaxLine&&f(t),e.mustUpdate=e.viewChanged||e.forceUpdate||null!=e.scrollTop||e.scrollToPos&&(e.scrollToPos.from.line<n.viewFrom||e.scrollToPos.to.line>=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new L(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function Ln(e){e.updatedDisplay=e.mustUpdate&&T(e.cm,e.update)}function Mn(e){var t=e.cm,n=t.display;e.updatedDisplay&&D(t),e.barMeasure=p(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=Zt(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+$t(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-jt(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection())}function Tn(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style.minWidth=e.adju
 stWidthTo+"px",e.maxScrollLeft<t.doc.scrollLeft&&nr(t,Math.min(t.display.scroller.scrollLeft,e.maxScrollLeft),!0),t.display.maxLineChanged=!1),e.preparedSelection&&t.display.input.showSelection(e.preparedSelection),e.updatedDisplay&&O(t,e.barMeasure),(e.updatedDisplay||e.startHeight!=t.doc.height)&&y(t,e.barMeasure),e.selectionChanged&&zt(t),t.state.focused&&e.updateInput&&t.display.input.reset(e.typing),e.focus&&e.focus==Uo()&&Y(e.cm)}function Nn(e){var t=e.cm,n=t.display,r=t.doc;if(e.updatedDisplay&&N(t,e.update),null==n.wheelStartX||null==e.scrollTop&&null==e.scrollLeft&&!e.scrollToPos||(n.wheelStartX=n.wheelStartY=null),null==e.scrollTop||n.scroller.scrollTop==e.scrollTop&&!e.forceScroll||(r.scrollTop=Math.max(0,Math.min(n.scroller.scrollHeight-n.scroller.clientHeight,e.scrollTop)),n.scrollbars.setScrollTop(r.scrollTop),n.scroller.scrollTop=r.scrollTop),null==e.scrollLeft||n.scroller.scrollLeft==e.scrollLeft&&!e.forceScroll||(r.scrollLeft=Math.max(0,Math.min(n.scroller.scrollWid
 th-jt(t),e.scrollLeft)),n.scrollbars.setScrollLeft(r.scrollLeft),n.scroller.scrollLeft=r.scrollLeft,w(t)),e.scrollToPos){var i=Dr(t,mt(r,e.scrollToPos.from),mt(r,e.scrollToPos.to),e.scrollToPos.margin);e.scrollToPos.isCursor&&t.state.focused&&Or(t,i)}var o=e.maybeHiddenMarkers,l=e.maybeUnhiddenMarkers;if(o)for(var s=0;s<o.length;++s)o[s].lines.length||Ms(o[s],"hide");if(l)for(var s=0;s<l.length;++s)l[s].lines.length&&Ms(l[s],"unhide");n.wrapper.offsetHeight&&(r.scrollTop=t.display.scroller.scrollTop),e.changeObjs&&Ms(t,"changes",t,e.changeObjs),e.update&&e.update.finish()}function An(e,t){if(e.curOp)return t();xn(e);try{return t()}finally{Cn(e)}}function On(e,t){return function(){if(e.curOp)return t.apply(e,arguments);xn(e);try{return t.apply(e,arguments)}finally{Cn(e)}}}function Dn(e){return function(){if(this.curOp)return e.apply(this,arguments);xn(this);try{return e.apply(this,arguments)}finally{Cn(this)}}}function Wn(e){return function(){var t=this.cm;if(!t||t.curOp)return e.app
 ly(this,arguments);xn(t);try{return e.apply(this,arguments)}finally{Cn(t)}}}function Hn(e,t,n){this.line=t,this.rest=mi(t),this.size=this.rest?Qi(Oo(this.rest))-n+1:1,this.node=this.text=null,this.hidden=bi(e,t)}function En(e,t,n){for(var r,i=[],o=t;n>o;o=r){var l=new Hn(e.doc,Ki(e.doc,o),o);r=o+l.size,i.push(l)}return i}function In(e,t,n,r){null==t&&(t=e.doc.first),null==n&&(n=e.doc.first+e.doc.size),r||(r=0);var i=e.display;if(r&&n<i.viewTo&&(null==i.updateLineNumbers||i.updateLineNumbers>t)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)Dl&&vi(e.doc,t)<i.viewTo&&zn(e);else if(n<=i.viewFrom)Dl&&yi(e.doc,n+r)>i.viewFrom?zn(e):(i.viewFrom+=r,i.viewTo+=r);else if(t<=i.viewFrom&&n>=i.viewTo)zn(e);else if(t<=i.viewFrom){var o=Bn(e,n,n+r,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=r):zn(e)}else if(n>=i.viewTo){var o=Bn(e,t,t,-1);o?(i.view=i.view.slice(0,o.index),i.viewTo=o.lineN):zn(e)}else{var l=Bn(e,t,t,-1),s=Bn(e,n,n+r,1);l&&s?(i.view=i.view.slice(0,l
 .index).concat(En(e,l.lineN,s.lineN)).concat(i.view.slice(s.index)),i.viewTo+=r):zn(e)}var a=i.externalMeasured;a&&(n<a.lineN?a.lineN+=r:t<a.lineN+a.size&&(i.externalMeasured=null))}function Fn(e,t,n){e.curOp.viewChanged=!0;var r=e.display,i=e.display.externalMeasured;if(i&&t>=i.lineN&&t<i.lineN+i.size&&(r.externalMeasured=null),!(t<r.viewFrom||t>=r.viewTo)){var o=r.view[Pn(e,t)];if(null!=o.node){var l=o.changes||(o.changes=[]);-1==Do(l,n)&&l.push(n)}}}function zn(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function Pn(e,t){if(t>=e.display.viewTo)return null;if(t-=e.display.viewFrom,0>t)return null;for(var n=e.display.view,r=0;r<n.length;r++)if(t-=n[r].size,0>t)return r}function Bn(e,t,n,r){var i,o=Pn(e,t),l=e.display.view;if(!Dl||n==e.doc.first+e.doc.size)return{index:o,lineN:n};for(var s=0,a=e.display.viewFrom;o>s;s++)a+=l[s].size;if(a!=t){if(r>0){if(o==l.length-1)return null;i=a+l[o].size-t,o++}else i=a-t;t+=i,n+=i}for(;vi(e.doc,n)!
 =n;){if(o==(0>r?0:l.length-1))return null;n+=r*l[o-(0>r?1:0)].size,o+=r}return{index:o,lineN:n}}function _n(e,t,n){var r=e.display,i=r.view;0==i.length||t>=r.viewTo||n<=r.viewFrom?(r.view=En(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=En(e,t,r.viewFrom).concat(r.view):r.viewFrom<t&&(r.view=r.view.slice(Pn(e,t))),r.viewFrom=t,r.viewTo<n?r.view=r.view.concat(En(e,r.viewTo,n)):r.viewTo>n&&(r.view=r.view.slice(0,Pn(e,n)))),r.viewTo=n}function Rn(e){for(var t=e.display.view,n=0,r=0;r<t.length;r++){var i=t[r];i.hidden||i.node&&!i.changes||++n}return n}function qn(e){function t(){i.activeTouch&&(o=setTimeout(function(){i.activeTouch=null},1e3),l=i.activeTouch,l.end=+new Date)}function n(e){if(1!=e.touches.length)return!1;var t=e.touches[0];return t.radiusX<=1&&t.radiusY<=1}function r(e,t){if(null==t.left)return!0;var n=t.left-e.left,r=t.top-e.top;return n*n+r*r>400}var i=e.display;Ss(i.scroller,"mousedown",On(e,Vn)),pl&&11>gl?Ss(i.scroller,"dblclick",On(e,function(t){if(!ko(e,t)){var n=jn(e,
 t);if(n&&!Qn(e,t)&&!$n(e.display,t)){ws(t);var r=e.findWordAt(n);wt(e.doc,r.anchor,r.head)}}})):Ss(i.scroller,"dblclick",function(t){ko(e,t)||ws(t)}),Al||Ss(i.scroller,"contextmenu",function(t){mr(e,t)});var o,l={end:0};Ss(i.scroller,"touchstart",function(e){if(!n(e)){clearTimeout(o);var t=+new Date;i.activeTouch={start:t,moved:!1,prev:t-l.end<=300?l:null},1==e.touches.length&&(i.activeTouch.left=e.touches[0].pageX,i.activeTouch.top=e.touches[0].pageY)}}),Ss(i.scroller,"touchmove",function(){i.activeTouch&&(i.activeTouch.moved=!0)}),Ss(i.scroller,"touchend",function(n){var o=i.activeTouch;if(o&&!$n(i,n)&&null!=o.left&&!o.moved&&new Date-o.start<300){var l,s=e.coordsChar(i.activeTouch,"page");l=!o.prev||r(o,o.prev)?new ft(s,s):!o.prev.prev||r(o,o.prev.prev)?e.findWordAt(s):new ft(Wl(s.line,0),mt(e.doc,Wl(s.line+1,0))),e.setSelection(l.anchor,l.head),e.focus(),ws(n)}t()}),Ss(i.scroller,"touchcancel",t),Ss(i.scroller,"scroll",function(){i.scroller.clientHeight&&(tr(e,i.scroller.scrollT
 op),nr(e,i.scroller.scrollLeft,!0),Ms(e,"scroll",e))}),Ss(i.scroller,"mousewheel",function(t){rr(e,t)}),Ss(i.scroller,"DOMMouseScroll",function(t){rr(e,t)}),Ss(i.wrapper,"scroll",function(){i.wrapper.scrollTop=i.wrapper.scrollLeft=0}),i.dragFunctions={simple:function(t){ko(e,t)||ks(t)},start:function(t){er(e,t)},drop:On(e,Jn)};var s=i.input.getField();Ss(s,"keyup",function(t){hr.call(e,t)}),Ss(s,"keydown",On(e,ur)),Ss(s,"keypress",On(e,fr)),Ss(s,"focus",Fo(pr,e)),Ss(s,"blur",Fo(gr,e))}function Un(t,n,r){var i=r&&r!=e.Init;if(!n!=!i){var o=t.display.dragFunctions,l=n?Ss:Ls;l(t.display.scroller,"dragstart",o.start),l(t.display.scroller,"dragenter",o.simple),l(t.display.scroller,"dragover",o.simple),l(t.display.scroller,"drop",o.drop)}}function Gn(e){var t=e.display;(t.lastWrapHeight!=t.wrapper.clientHeight||t.lastWrapWidth!=t.wrapper.clientWidth)&&(t.cachedCharWidth=t.cachedTextHeight=t.cachedPaddingH=null,t.scrollbarsClipped=!1,e.setSize())}function $n(e,t){for(var n=bo(t);n!=e.wrapp
 er;n=n.parentNode)if(!n||1==n.nodeType&&"true"==n.getAttribute("cm-ignore-events")||n.parentNode==e.sizer&&n!=e.mover)return!0}function jn(e,t,n,r){var i=e.display;if(!n&&"true"==bo(t).getAttribute("cm-not-content"))return null;var o,l,s=i.lineSpace.getBoundingClientRect();try{o=t.clientX-s.left,l=t.clientY-s.top}catch(t){return null}var a,u=mn(e,o,l);if(r&&1==u.xRel&&(a=Ki(e.doc,u.line).text).length==u.ch){var c=Hs(a,a.length,e.options.tabSize)-a.length;u=Wl(u.line,Math.max(0,Math.round((o-Gt(e.display).left)/bn(e.display))-c))}return u}function Vn(e){var t=this,n=t.display;if(!(n.activeTouch&&n.input.supportsTouch()||ko(t,e))){if(n.shift=e.shiftKey,$n(n,e))return void(ml||(n.scroller.draggable=!1,setTimeout(function(){n.scroller.draggable=!0},100)));if(!Qn(t,e)){var r=jn(t,e);switch(window.focus(),xo(e)){case 1:r?Kn(t,e,r):bo(e)==n.scroller&&ws(e);break;case 2:ml&&(t.state.lastMiddleDown=+new Date),r&&wt(t.doc,r),setTimeout(function(){n.input.focus()},20),ws(e);break;case 3:Al?mr(
 t,e):dr(t)}}}}function Kn(e,t,n){pl?setTimeout(Fo(Y,e),0):e.curOp.focus=Uo();var r,i=+new Date;zl&&zl.time>i-400&&0==Hl(zl.pos,n)?r="triple":Fl&&Fl.time>i-400&&0==Hl(Fl.pos,n)?(r="double",zl={time:i,pos:n}):(r="single",Fl={time:i,pos:n});var o,l=e.doc.sel,s=Ll?t.metaKey:t.ctrlKey;e.options.dragDrop&&js&&!Z(e)&&"single"==r&&(o=l.contains(n))>-1&&(Hl((o=l.ranges[o]).from(),n)<0||n.xRel>0)&&(Hl(o.to(),n)>0||n.xRel<0)?Xn(e,t,n,s):Yn(e,t,n,r,s)}function Xn(e,t,n,r){var i=e.display,o=+new Date,l=On(e,function(s){ml&&(i.scroller.draggable=!1),e.state.draggingText=!1,Ls(document,"mouseup",l),Ls(i.scroller,"drop",l),Math.abs(t.clientX-s.clientX)+Math.abs(t.clientY-s.clientY)<10&&(ws(s),!r&&+new Date-200<o&&wt(e.doc,n),ml||pl&&9==gl?setTimeout(function(){document.body.focus(),i.input.focus()},20):i.input.focus())});ml&&(i.scroller.draggable=!0),e.state.draggingText=l,i.scroller.dragDrop&&i.scroller.dragDrop(),Ss(document,"mouseup",l),Ss(i.scroller,"drop",l)}function Yn(e,t,n,r,i){function o(t
 ){if(0!=Hl(m,t))if(m=t,"rect"==r){for(var i=[],o=e.options.tabSize,l=Hs(Ki(u,n.line).text,n.ch,o),s=Hs(Ki(u,t.line).text,t.ch,o),a=Math.min(l,s),d=Math.max(l,s),p=Math.min(n.line,t.line),g=Math.min(e.lastLine(),Math.max(n.line,t.line));g>=p;p++){var v=Ki(u,p).text,y=No(v,a,o);a==d?i.push(new ft(Wl(p,y),Wl(p,y))):v.length>y&&i.push(new ft(Wl(p,y),Wl(p,No(v,d,o))))}i.length||i.push(new ft(n,n)),Tt(u,dt(f.ranges.slice(0,h).concat(i),h),{origin:"*mouse",scroll:!1}),e.scrollIntoView(t)}else{var b=c,x=b.anchor,w=t;if("single"!=r){if("double"==r)var C=e.findWordAt(t);else var C=new ft(Wl(t.line,0),mt(u,Wl(t.line+1,0)));Hl(C.anchor,x)>0?(w=C.head,x=X(b.from(),C.anchor)):(w=C.anchor,x=K(b.to(),C.head))}var i=f.ranges.slice(0);i[h]=new ft(mt(u,x),w),Tt(u,dt(i,h),Ds)}}function l(t){var n=++y,i=jn(e,t,!0,"rect"==r);if(i)if(0!=Hl(i,m)){e.curOp.focus=Uo(),o(i);var s=x(a,u);(i.line>=s.to||i.line<s.from)&&setTimeout(On(e,function(){y==n&&l(t)}),150)}else{var c=t.clientY<v.top?-20:t.clientY>v.bottom
 ?20:0;c&&setTimeout(On(e,function(){y==n&&(a.scroller.scrollTop+=c,l(t))}),50)}}function s(e){y=1/0,ws(e),a.input.focus(),Ls(document,"mousemove",b),Ls(document,"mouseup",w),u.history.lastSelOrigin=null}var a=e.display,u=e.doc;ws(t);var c,h,f=u.sel,d=f.ranges;if(i&&!t.shiftKey?(h=u.sel.contains(n),c=h>-1?d[h]:new ft(n,n)):(c=u.sel.primary(),h=u.sel.primIndex),t.altKey)r="rect",i||(c=new ft(n,n)),n=jn(e,t,!0,!0),h=-1;else if("double"==r){var p=e.findWordAt(n);c=e.display.shift||u.extend?xt(u,c,p.anchor,p.head):p}else if("triple"==r){var g=new ft(Wl(n.line,0),mt(u,Wl(n.line+1,0)));c=e.display.shift||u.extend?xt(u,c,g.anchor,g.head):g}else c=xt(u,c,n);i?-1==h?(h=d.length,Tt(u,dt(d.concat([c]),h),{scroll:!1,origin:"*mouse"})):d.length>1&&d[h].empty()&&"single"==r&&!t.shiftKey?(Tt(u,dt(d.slice(0,h).concat(d.slice(h+1)),0)),f=u.sel):kt(u,h,c,Ds):(h=0,Tt(u,new ht([c],0),Ds),f=u.sel);var m=n,v=a.wrapper.getBoundingClientRect(),y=0,b=On(e,function(e){xo(e)?l(e):s(e)}),w=On(e,s);Ss(document,"
 mousemove",b),Ss(document,"mouseup",w)}function Zn(e,t,n,r,i){try{var o=t.clientX,l=t.clientY}catch(t){return!1}if(o>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&ws(t);var s=e.display,a=s.lineDiv.getBoundingClientRect();if(l>a.bottom||!Lo(e,n))return yo(t);l-=a.top-s.viewOffset;for(var u=0;u<e.options.gutters.length;++u){var c=s.gutters.childNodes[u];if(c&&c.getBoundingClientRect().right>=o){var h=Ji(e.doc,l),f=e.options.gutters[u];return i(e,n,e,h,f,t),yo(t)}}}function Qn(e,t){return Zn(e,t,"gutterClick",!0,wo)}function Jn(e){var t=this;if(!ko(t,e)&&!$n(t.display,e)){ws(e),pl&&(Rl=+new Date);var n=jn(t,e,!0),r=e.dataTransfer.files;if(n&&!Z(t))if(r&&r.length&&window.FileReader&&window.File)for(var i=r.length,o=Array(i),l=0,s=function(e,r){var s=new FileReader;s.onload=On(t,function(){if(o[r]=s.result,++l==i){n=mt(t.doc,n);var e={from:n,to:n,text:Vs(o.join("\n")),origin:"paste"};kr(t.doc,e),Mt(t.doc,pt(n,Vl(e)))}}),s.readAsText(e)},a=0;i>a;++a)s(r[a],a);el
 se{if(t.state.draggingText&&t.doc.sel.contains(n)>-1)return t.state.draggingText(e),void setTimeout(function(){t.display.input.focus()},20);try{var o=e.dataTransfer.getData("Text");if(o){if(t.state.draggingText&&!(Ll?e.altKey:e.ctrlKey))var u=t.listSelections();if(Nt(t.doc,pt(n,n)),u)for(var a=0;a<u.length;++a)Ar(t.doc,"",u[a].anchor,u[a].head,"drag");t.replaceSelection(o,"around","paste"),t.display.input.focus()}}catch(e){}}}}function er(e,t){if(pl&&(!e.state.draggingText||+new Date-Rl<100))return void ks(t);if(!ko(e,t)&&!$n(e.display,t)&&(t.dataTransfer.setData("Text",e.getSelection()),t.dataTransfer.setDragImage&&!xl)){var n=_o("img",null,null,"position: fixed; left: 0; top: 0;");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",bl&&(n.width=n.height=1,e.display.wrapper.appendChild(n),n._top=n.offsetTop),t.dataTransfer.setDragImage(n,0,0),bl&&n.parentNode.removeChild(n)}}function tr(e,t){Math.abs(e.doc.scrollTop-t)<2||(e.doc.scrollTop=t,hl||A(e,{t
 op:t}),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t),e.display.scrollbars.setScrollTop(t),hl&&A(e),Pt(e,100))}function nr(e,t,n){(n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)||(t=Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth),e.doc.scrollLeft=t,w(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function rr(e,t){var n=Gl(t),r=n.x,i=n.y,o=e.display,l=o.scroller;if(r&&l.scrollWidth>l.clientWidth||i&&l.scrollHeight>l.clientHeight){if(i&&Ll&&ml)e:for(var s=t.target,a=o.view;s!=l;s=s.parentNode)for(var u=0;u<a.length;u++)if(a[u].node==s){e.display.currentWheelTarget=s;break e}if(r&&!hl&&!bl&&null!=Ul)return i&&tr(e,Math.max(0,Math.min(l.scrollTop+i*Ul,l.scrollHeight-l.clientHeight))),nr(e,Math.max(0,Math.min(l.scrollLeft+r*Ul,l.scrollWidth-l.clientWidth))),ws(t),void(o.wheelStartX=null);if(i&&null!=Ul){var c=i*Ul,h=e.doc.scrollTop,f=h+o.wrapper.clientHeight;0>c?h=Math.max(0
 ,h+c-50):f=Math.min(e.doc.height,f+c+50),A(e,{top:h,bottom:f})}20>ql&&(null==o.wheelStartX?(o.wheelStartX=l.scrollLeft,o.wheelStartY=l.scrollTop,o.wheelDX=r,o.wheelDY=i,setTimeout(function(){if(null!=o.wheelStartX){var e=l.scrollLeft-o.wheelStartX,t=l.scrollTop-o.wheelStartY,n=t&&o.wheelDY&&t/o.wheelDY||e&&o.wheelDX&&e/o.wheelDX;o.wheelStartX=o.wheelStartY=null,n&&(Ul=(Ul*ql+n)/(ql+1),++ql)}},200)):(o.wheelDX+=r,o.wheelDY+=i))}}function ir(e,t,n){if("string"==typeof t&&(t=is[t],!t))return!1;e.display.input.ensurePolled();var r=e.display.shift,i=!1;try{Z(e)&&(e.state.suppressEdits=!0),n&&(e.display.shift=!1),i=t(e)!=As}finally{e.display.shift=r,e.state.suppressEdits=!1}return i}function or(e,t,n){for(var r=0;r<e.state.keyMaps.length;r++){var i=ls(t,e.state.keyMaps[r],n,e);if(i)return i}return e.options.extraKeys&&ls(t,e.options.extraKeys,n,e)||ls(t,e.options.keyMap,n,e)}function lr(e,t,n,r){var i=e.state.keySeq;if(i){if(ss(t))return"handled";$l.set(50,function(){e.state.keySeq==i&&(e
 .state.keySeq=null,e.display.input.reset())}),t=i+" "+t}var o=or(e,t,r);return"multi"==o&&(e.state.keySeq=t),"handled"==o&&wo(e,"keyHandled",e,t,n),("handled"==o||"multi"==o)&&(ws(n),zt(e)),i&&!o&&/\'$/.test(t)?(ws(n),!0):!!o}function sr(e,t){var n=as(t,!0);return n?t.shiftKey&&!e.state.keySeq?lr(e,"Shift-"+n,t,function(t){return ir(e,t,!0)})||lr(e,n,t,function(t){return("string"==typeof t?/^go[A-Z]/.test(t):t.motion)?ir(e,t):void 0}):lr(e,n,t,function(t){return ir(e,t)}):!1}function ar(e,t,n){return lr(e,"'"+n+"'",t,function(t){return ir(e,t,!0)})}function ur(e){var t=this;if(t.curOp.focus=Uo(),!ko(t,e)){pl&&11>gl&&27==e.keyCode&&(e.returnValue=!1);var n=e.keyCode;t.display.shift=16==n||e.shiftKey;var r=sr(t,e);bl&&(jl=r?n:null,!r&&88==n&&!Xs&&(Ll?e.metaKey:e.ctrlKey)&&t.replaceSelection("",null,"cut")),18!=n||/\bCodeMirror-crosshair\b/.test(t.display.lineDiv.className)||cr(t)}}function cr(e){function t(e){18!=e.keyCode&&e.altKey||(Us(n,"CodeMirror-crosshair"),Ls(document,"keyup",t
 ),Ls(document,"mouseover",t))}var n=e.display.lineDiv;Gs(n,"CodeMirror-crosshair"),Ss(document,"keyup",t),Ss(document,"mouseover",t)}function hr(e){16==e.keyCode&&(this.doc.sel.shift=!1),ko(this,e)}function fr(e){var t=this;if(!($n(t.display,e)||ko(t,e)||e.ctrlKey&&!e.altKey||Ll&&e.metaKey)){var n=e.keyCode,r=e.charCode;if(bl&&n==jl)return jl=null,void ws(e);if(!bl||e.which&&!(e.which<10)||!sr(t,e)){var i=String.fromCharCode(null==r?n:r);ar(t,e,i)||t.display.input.onKeyPress(e)}}}function dr(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,gr(e))},100)}function pr(e){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1),"nocursor"!=e.options.readOnly&&(e.state.focused||(Ms(e,"focus",e),e.state.focused=!0,Gs(e.display.wrapper,"CodeMirror-focused"),e.curOp||e.display.selForContextMenu==e.doc.sel||(e.display.input.reset(),ml&&setTimeout(function(){e.display.input.reset(!0)},20)),e.display.input.receivedFocus()),zt(e))}fu
 nction gr(e){e.state.delayingBlurEvent||(e.state.focused&&(Ms(e,"blur",e),e.state.focused=!1,Us(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout(function(){e.state.focused||(e.display.shift=!1)},150))}function mr(e,t){$n(e.display,t)||vr(e,t)||e.display.input.onContextMenu(t)}function vr(e,t){return Lo(e,"gutterContextMenu")?Zn(e,t,"gutterContextMenu",!1,Ms):!1}function yr(e,t){if(Hl(e,t.from)<0)return e;if(Hl(e,t.to)<=0)return Vl(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=Vl(t).ch-t.to.ch),Wl(n,r)}function br(e,t){for(var n=[],r=0;r<e.sel.ranges.length;r++){var i=e.sel.ranges[r];n.push(new ft(yr(i.anchor,t),yr(i.head,t)))}return dt(n,e.sel.primIndex)}function xr(e,t,n){return e.line==t.line?Wl(n.line,e.ch-t.ch+n.ch):Wl(n.line+(e.line-t.line),e.ch)}function wr(e,t,n){for(var r=[],i=Wl(e.first,0),o=i,l=0;l<t.length;l++){var s=t[l],a=xr(s.from,i,o),u=xr(Vl(s),i,o);if(i=s.to,o=u,"around"==n){var c=e.s
 el.ranges[l],h=Hl(c.head,c.anchor)<0;r[l]=new ft(h?u:a,h?a:u)}else r[l]=new ft(a,a)}return new ht(r,e.sel.primIndex)}function Cr(e,t,n){var r={canceled:!1,from:t.from,to:t.to,text:t.text,origin:t.origin,cancel:function(){this.canceled=!0}};return n&&(r.update=function(t,n,r,i){t&&(this.from=mt(e,t)),n&&(this.to=mt(e,n)),r&&(this.text=r),void 0!==i&&(this.origin=i)}),Ms(e,"beforeChange",e,r),e.cm&&Ms(e.cm,"beforeChange",e.cm,r),r.canceled?null:{from:r.from,to:r.to,text:r.text,origin:r.origin}}function kr(e,t,n){if(e.cm){if(!e.cm.curOp)return On(e.cm,kr)(e,t,n);if(e.cm.state.suppressEdits)return}if(!(Lo(e,"beforeChange")||e.cm&&Lo(e.cm,"beforeChange"))||(t=Cr(e,t,!0))){var r=Ol&&!n&&oi(e,t.from,t.to);if(r)for(var i=r.length-1;i>=0;--i)Sr(e,{from:r[i].from,to:r[i].to,text:i?[""]:t.text});else Sr(e,t)}}function Sr(e,t){if(1!=t.text.length||""!=t.text[0]||0!=Hl(t.from,t.to)){var n=br(e,t);lo(e,t,n,e.cm?e.cm.curOp.id:0/0),Tr(e,t,n,ni(e,t));var r=[];ji(e,function(e,n){n||-1!=Do(r,e.history
 )||(vo(e.history,t),r.push(e.history)),Tr(e,t,null,ni(e,t))})}}function Lr(e,t,n){if(!e.cm||!e.cm.state.suppressEdits){for(var r,i=e.history,o=e.sel,l="undo"==t?i.done:i.undone,s="undo"==t?i.undone:i.done,a=0;a<l.length&&(r=l[a],n?!r.ranges||r.equals(e.sel):r.ranges);a++);if(a!=l.length){for(i.lastOrigin=i.lastSelOrigin=null;r=l.pop(),r.ranges;){if(uo(r,s),n&&!r.equals(e.sel))return void Tt(e,r,{clearRedo:!1});o=r}var u=[];uo(o,s),s.push({changes:u,generation:i.generation}),i.generation=r.generation||++i.maxGeneration;for(var c=Lo(e,"beforeChange")||e.cm&&Lo(e.cm,"beforeChange"),a=r.changes.length-1;a>=0;--a){var h=r.changes[a];if(h.origin=t,c&&!Cr(e,h,!1))return void(l.length=0);u.push(ro(e,h));var f=a?br(e,h):Oo(l);Tr(e,h,f,ii(e,h)),!a&&e.cm&&e.cm.scrollIntoView({from:h.from,to:Vl(h)});var d=[];ji(e,function(e,t){t||-1!=Do(d,e.history)||(vo(e.history,h),d.push(e.history)),Tr(e,h,null,ii(e,h))})}}}}function Mr(e,t){if(0!=t&&(e.first+=t,e.sel=new ht(Wo(e.sel.ranges,function(e){retur
 n new ft(Wl(e.anchor.line+t,e.anchor.ch),Wl(e.head.line+t,e.head.ch))}),e.sel.primIndex),e.cm)){In(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;r<n.viewTo;r++)Fn(e.cm,r,"gutter")}}function Tr(e,t,n,r){if(e.cm&&!e.cm.curOp)return On(e.cm,Tr)(e,t,n,r);if(t.to.line<e.first)return void Mr(e,t.text.length-1-(t.to.line-t.from.line));if(!(t.from.line>e.lastLine())){if(t.from.line<e.first){var i=t.text.length-1-(e.first-t.from.line);Mr(e,i),t={from:Wl(e.first,0),to:Wl(t.to.line+i,t.to.ch),text:[Oo(t.text)],origin:t.origin}}var o=e.lastLine();t.to.line>o&&(t={from:t.from,to:Wl(o,Ki(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=Xi(e,t.from,t.to),n||(n=br(e,t)),e.cm?Nr(e.cm,t,r):Ui(e,t,r),Nt(e,n,Os)}}function Nr(e,t,n){var r=e.doc,i=e.display,l=t.from,s=t.to,a=!1,u=l.line;e.options.lineWrapping||(u=Qi(gi(Ki(r,l.line))),r.iter(u,s.line+1,function(e){return e==i.maxLine?(a=!0,!0):void 0})),r.sel.contains(t.from,t.to)>-1&&So(e),Ui(r,t,n,o(e)),e.options.lineWrappi
 ng||(r.iter(u,l.line+t.text.length,function(e){var t=h(e);t>i.maxLineLength&&(i.maxLine=e,i.maxLineLength=t,i.maxLineChanged=!0,a=!1)
-}),a&&(e.curOp.updateMaxLine=!0)),r.frontier=Math.min(r.frontier,l.line),Pt(e,400);var c=t.text.length-(s.line-l.line)-1;t.full?In(e):l.line!=s.line||1!=t.text.length||qi(e.doc,t)?In(e,l.line,s.line+1,c):Fn(e,l.line,"text");var f=Lo(e,"changes"),d=Lo(e,"change");if(d||f){var p={from:l,to:s,text:t.text,removed:t.removed,origin:t.origin};d&&wo(e,"change",e,p),f&&(e.curOp.changeObjs||(e.curOp.changeObjs=[])).push(p)}e.display.selForContextMenu=null}function Ar(e,t,n,r,i){if(r||(r=n),Hl(r,n)<0){var o=r;r=n,n=o}"string"==typeof t&&(t=Vs(t)),kr(e,{from:n,to:r,text:t,origin:i})}function Or(e,t){if(!ko(e,"scrollCursorIntoView")){var n=e.display,r=n.sizer.getBoundingClientRect(),i=null;if(t.top+r.top<0?i=!0:t.bottom+r.top>(window.innerHeight||document.documentElement.clientHeight)&&(i=!1),null!=i&&!Cl){var o=_o("div","​",null,"position: absolute; top: "+(t.top-n.viewOffset-qt(e.display))+"px; height: "+(t.bottom-t.top+$t(e)+n.barHeight)+"px; left: "+t.left+"px; width: 2px;");e.display.line
 Space.appendChild(o),o.scrollIntoView(i),e.display.lineSpace.removeChild(o)}}}function Dr(e,t,n,r){null==r&&(r=0);for(var i=0;5>i;i++){var o=!1,l=dn(e,t),s=n&&n!=t?dn(e,n):l,a=Hr(e,Math.min(l.left,s.left),Math.min(l.top,s.top)-r,Math.max(l.left,s.left),Math.max(l.bottom,s.bottom)+r),u=e.doc.scrollTop,c=e.doc.scrollLeft;if(null!=a.scrollTop&&(tr(e,a.scrollTop),Math.abs(e.doc.scrollTop-u)>1&&(o=!0)),null!=a.scrollLeft&&(nr(e,a.scrollLeft),Math.abs(e.doc.scrollLeft-c)>1&&(o=!0)),!o)break}return l}function Wr(e,t,n,r,i){var o=Hr(e,t,n,r,i);null!=o.scrollTop&&tr(e,o.scrollTop),null!=o.scrollLeft&&nr(e,o.scrollLeft)}function Hr(e,t,n,r,i){var o=e.display,l=yn(e.display);0>n&&(n=0);var s=e.curOp&&null!=e.curOp.scrollTop?e.curOp.scrollTop:o.scroller.scrollTop,a=Vt(e),u={};i-n>a&&(i=n+a);var c=e.doc.height+Ut(o),h=l>n,f=i>c-l;if(s>n)u.scrollTop=h?0:n;else if(i>s+a){var d=Math.min(n,(f?c:i)-a);d!=s&&(u.scrollTop=d)}var p=e.curOp&&null!=e.curOp.scrollLeft?e.curOp.scrollLeft:o.scroller.scrollLe
 ft,g=jt(e)-(e.options.fixedGutter?o.gutters.offsetWidth:0),m=r-t>g;return m&&(r=t+g),10>t?u.scrollLeft=0:p>t?u.scrollLeft=Math.max(0,t-(m?0:10)):r>g+p-3&&(u.scrollLeft=r+(m?0:10)-g),u}function Er(e,t,n){(null!=t||null!=n)&&Fr(e),null!=t&&(e.curOp.scrollLeft=(null==e.curOp.scrollLeft?e.doc.scrollLeft:e.curOp.scrollLeft)+t),null!=n&&(e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+n)}function Ir(e){Fr(e);var t=e.getCursor(),n=t,r=t;e.options.lineWrapping||(n=t.ch?Wl(t.line,t.ch-1):t,r=Wl(t.line,t.ch+1)),e.curOp.scrollToPos={from:n,to:r,margin:e.options.cursorScrollMargin,isCursor:!0}}function Fr(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;var n=pn(e,t.from),r=pn(e,t.to),i=Hr(e,Math.min(n.left,r.left),Math.min(n.top,r.top)-t.margin,Math.max(n.right,r.right),Math.max(n.bottom,r.bottom)+t.margin);e.scrollTo(i.scrollLeft,i.scrollTop)}}function zr(e,t,n,r){var i,o=e.doc;null==n&&(n="add"),"smart"==n&&(o.mode.indent?i=Rt(e,t):n="prev");var l=e.o
 ptions.tabSize,s=Ki(o,t),a=Hs(s.text,null,l);s.stateAfter&&(s.stateAfter=null);var u,c=s.text.match(/^\s*/)[0];if(r||/\S/.test(s.text)){if("smart"==n&&(u=o.mode.indent(i,s.text.slice(c.length),s.text),u==As||u>150)){if(!r)return;n="prev"}}else u=0,n="not";"prev"==n?u=t>o.first?Hs(Ki(o,t-1).text,null,l):0:"add"==n?u=a+e.options.indentUnit:"subtract"==n?u=a-e.options.indentUnit:"number"==typeof n&&(u=a+n),u=Math.max(0,u);var h="",f=0;if(e.options.indentWithTabs)for(var d=Math.floor(u/l);d;--d)f+=l,h+="	";if(u>f&&(h+=Ao(u-f)),h!=c)return Ar(o,h,Wl(t,0),Wl(t,c.length),"+input"),s.stateAfter=null,!0;for(var d=0;d<o.sel.ranges.length;d++){var p=o.sel.ranges[d];if(p.head.line==t&&p.head.ch<c.length){var f=Wl(t,c.length);kt(o,d,new ft(f,f));break}}}function Pr(e,t,n,r){var i=t,o=t;return"number"==typeof t?o=Ki(e,gt(e,t)):i=Qi(t),null==i?null:(r(o,i)&&e.cm&&Fn(e.cm,i,n),o)}function Br(e,t){for(var n=e.doc.sel.ranges,r=[],i=0;i<n.length;i++){for(var o=t(n[i]);r.length&&Hl(o.from,Oo(r).to)<=0;
 ){var l=r.pop();if(Hl(l.from,o.from)<0){o.from=l.from;break}}r.push(o)}An(e,function(){for(var t=r.length-1;t>=0;t--)Ar(e.doc,"",r[t].from,r[t].to,"+delete");Ir(e)})}function _r(e,t,n,r,i){function o(){var t=s+n;return t<e.first||t>=e.first+e.size?h=!1:(s=t,c=Ki(e,t))}function l(e){var t=(i?ul:cl)(c,a,n,!0);if(null==t){if(e||!o())return h=!1;a=i?(0>n?nl:tl)(c):0>n?c.text.length:0}else a=t;return!0}var s=t.line,a=t.ch,u=n,c=Ki(e,s),h=!0;if("char"==r)l();else if("column"==r)l(!0);else if("word"==r||"group"==r)for(var f=null,d="group"==r,p=e.cm&&e.cm.getHelper(t,"wordChars"),g=!0;!(0>n)||l(!g);g=!1){var m=c.text.charAt(a)||"\n",v=zo(m,p)?"w":d&&"\n"==m?"n":!d||/\s/.test(m)?null:"p";if(!d||g||v||(v="s"),f&&f!=v){0>n&&(n=1,l());break}if(v&&(f=v),n>0&&!l(!g))break}var y=Wt(e,Wl(s,a),u,!0);return h||(y.hitSide=!0),y}function Rr(e,t,n,r){var i,o=e.doc,l=t.left;if("page"==r){var s=Math.min(e.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight);i=t.top+n*(s-
 (0>n?1.5:.5)*yn(e.display))}else"line"==r&&(i=n>0?t.bottom+3:t.top-3);for(;;){var a=mn(e,l,i);if(!a.outside)break;if(0>n?0>=i:i>=o.height){a.hitSide=!0;break}i+=5*n}return a}function qr(t,n,r,i){e.defaults[t]=n,r&&(Xl[t]=i?function(e,t,n){n!=Yl&&r(e,t,n)}:r)}function Ur(e){for(var t,n,r,i,o=e.split(/-(?!$)/),e=o[o.length-1],l=0;l<o.length-1;l++){var s=o[l];if(/^(cmd|meta|m)$/i.test(s))i=!0;else if(/^a(lt)?$/i.test(s))t=!0;else if(/^(c|ctrl|control)$/i.test(s))n=!0;else{if(!/^s(hift)$/i.test(s))throw new Error("Unrecognized modifier name: "+s);r=!0}}return t&&(e="Alt-"+e),n&&(e="Ctrl-"+e),i&&(e="Cmd-"+e),r&&(e="Shift-"+e),e}function Gr(e){return"string"==typeof e?os[e]:e}function $r(e,t,n,r,i){if(r&&r.shared)return jr(e,t,n,r,i);if(e.cm&&!e.cm.curOp)return On(e.cm,$r)(e,t,n,r,i);var o=new hs(e,i),l=Hl(t,n);if(r&&Io(r,o,!1),l>0||0==l&&o.clearWhenEmpty!==!1)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=_o("span",[o.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||o.wi
 dgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(pi(e,t.line,t,n,o)||t.line!=n.line&&pi(e,n.line,t,n,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");Dl=!0}o.addToHistory&&lo(e,{from:t,to:n,origin:"markText"},e.sel,0/0);var s,a=t.line,u=e.cm;if(e.iter(a,n.line+1,function(e){u&&o.collapsed&&!u.options.lineWrapping&&gi(e)==u.display.maxLine&&(s=!0),o.collapsed&&a!=t.line&&Zi(e,0),Jr(e,new Yr(o,a==t.line?t.ch:null,a==n.line?n.ch:null)),++a}),o.collapsed&&e.iter(t.line,n.line+1,function(t){bi(e,t)&&Zi(t,0)}),o.clearOnEnter&&Ss(o,"beforeCursorEnter",function(){o.clear()}),o.readOnly&&(Ol=!0,(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++cs,o.atomic=!0),u){if(s&&(u.curOp.updateMaxLine=!0),o.collapsed)In(u,t.line,n.line+1);else if(o.className||o.title||o.startStyle||o.endStyle||o.css)for(var c=t.line;c<=n.line;c++)Fn(u,c,"text");o.atomic&&Ot(u.doc),wo(
 u,"markerAdded",u,o)}return o}function jr(e,t,n,r,i){r=Io(r),r.shared=!1;var o=[$r(e,t,n,r,i)],l=o[0],s=r.widgetNode;return ji(e,function(e){s&&(r.widgetNode=s.cloneNode(!0)),o.push($r(e,mt(e,t),mt(e,n),r,i));for(var a=0;a<e.linked.length;++a)if(e.linked[a].isParent)return;l=Oo(o)}),new fs(o,l)}function Vr(e){return e.findMarks(Wl(e.first,0),e.clipPos(Wl(e.lastLine())),function(e){return e.parent})}function Kr(e,t){for(var n=0;n<t.length;n++){var r=t[n],i=r.find(),o=e.clipPos(i.from),l=e.clipPos(i.to);if(Hl(o,l)){var s=$r(e,o,l,r.primary,r.primary.type);r.markers.push(s),s.parent=r}}}function Xr(e){for(var t=0;t<e.length;t++){var n=e[t],r=[n.primary.doc];ji(n.primary.doc,function(e){r.push(e)});for(var i=0;i<n.markers.length;i++){var o=n.markers[i];-1==Do(r,o.doc)&&(o.parent=null,n.markers.splice(i--,1))}}}function Yr(e,t,n){this.marker=e,this.from=t,this.to=n}function Zr(e,t){if(e)for(var n=0;n<e.length;++n){var r=e[n];if(r.marker==t)return r}}function Qr(e,t){for(var n,r=0;r<e.len
 gth;++r)e[r]!=t&&(n||(n=[])).push(e[r]);return n}function Jr(e,t){e.markedSpans=e.markedSpans?e.markedSpans.concat([t]):[t],t.marker.attachLine(e)}function ei(e,t,n){if(e)for(var r,i=0;i<e.length;++i){var o=e[i],l=o.marker,s=null==o.from||(l.inclusiveLeft?o.from<=t:o.from<t);if(s||o.from==t&&"bookmark"==l.type&&(!n||!o.marker.insertLeft)){var a=null==o.to||(l.inclusiveRight?o.to>=t:o.to>t);(r||(r=[])).push(new Yr(l,o.from,a?null:o.to))}}return r}function ti(e,t,n){if(e)for(var r,i=0;i<e.length;++i){var o=e[i],l=o.marker,s=null==o.to||(l.inclusiveRight?o.to>=t:o.to>t);if(s||o.from==t&&"bookmark"==l.type&&(!n||o.marker.insertLeft)){var a=null==o.from||(l.inclusiveLeft?o.from<=t:o.from<t);(r||(r=[])).push(new Yr(l,a?null:o.from-t,null==o.to?null:o.to-t))}}return r}function ni(e,t){if(t.full)return null;var n=yt(e,t.from.line)&&Ki(e,t.from.line).markedSpans,r=yt(e,t.to.line)&&Ki(e,t.to.line).markedSpans;if(!n&&!r)return null;var i=t.from.ch,o=t.to.ch,l=0==Hl(t.from,t.to),s=ei(n,i,l),a=t
 i(r,o,l),u=1==t.text.length,c=Oo(t.text).length+(u?i:0);if(s)for(var h=0;h<s.length;++h){var f=s[h];if(null==f.to){var d=Zr(a,f.marker);d?u&&(f.to=null==d.to?null:d.to+c):f.to=i}}if(a)for(var h=0;h<a.length;++h){var f=a[h];if(null!=f.to&&(f.to+=c),null==f.from){var d=Zr(s,f.marker);d||(f.from=c,u&&(s||(s=[])).push(f))}else f.from+=c,u&&(s||(s=[])).push(f)}s&&(s=ri(s)),a&&a!=s&&(a=ri(a));var p=[s];if(!u){var g,m=t.text.length-2;if(m>0&&s)for(var h=0;h<s.length;++h)null==s[h].to&&(g||(g=[])).push(new Yr(s[h].marker,null,null));for(var h=0;m>h;++h)p.push(g);p.push(a)}return p}function ri(e){for(var t=0;t<e.length;++t){var n=e[t];null!=n.from&&n.from==n.to&&n.marker.clearWhenEmpty!==!1&&e.splice(t--,1)}return e.length?e:null}function ii(e,t){var n=fo(e,t),r=ni(e,t);if(!n)return r;if(!r)return n;for(var i=0;i<n.length;++i){var o=n[i],l=r[i];if(o&&l)e:for(var s=0;s<l.length;++s){for(var a=l[s],u=0;u<o.length;++u)if(o[u].marker==a.marker)continue e;o.push(a)}else l&&(n[i]=l)}return n}funct
 ion oi(e,t,n){var r=null;if(e.iter(t.line,n.line+1,function(e){if(e.markedSpans)for(var t=0;t<e.markedSpans.length;++t){var n=e.markedSpans[t].marker;!n.readOnly||r&&-1!=Do(r,n)||(r||(r=[])).push(n)}}),!r)return null;for(var i=[{from:t,to:n}],o=0;o<r.length;++o)for(var l=r[o],s=l.find(0),a=0;a<i.length;++a){var u=i[a];if(!(Hl(u.to,s.from)<0||Hl(u.from,s.to)>0)){var c=[a,1],h=Hl(u.from,s.from),f=Hl(u.to,s.to);(0>h||!l.inclusiveLeft&&!h)&&c.push({from:u.from,to:s.from}),(f>0||!l.inclusiveRight&&!f)&&c.push({from:s.to,to:u.to}),i.splice.apply(i,c),a+=c.length-1}}return i}function li(e){var t=e.markedSpans;if(t){for(var n=0;n<t.length;++n)t[n].marker.detachLine(e);e.markedSpans=null}}function si(e,t){if(t){for(var n=0;n<t.length;++n)t[n].marker.attachLine(e);e.markedSpans=t}}function ai(e){return e.inclusiveLeft?-1:0}function ui(e){return e.inclusiveRight?1:0}function ci(e,t){var n=e.lines.length-t.lines.length;if(0!=n)return n;var r=e.find(),i=t.find(),o=Hl(r.from,i.from)||ai(e)-ai(t);
 if(o)return-o;var l=Hl(r.to,i.to)||ui(e)-ui(t);return l?l:t.id-e.id}function hi(e,t){var n,r=Dl&&e.markedSpans;if(r)for(var i,o=0;o<r.length;++o)i=r[o],i.marker.collapsed&&null==(t?i.from:i.to)&&(!n||ci(n,i.marker)<0)&&(n=i.marker);return n}function fi(e){return hi(e,!0)}function di(e){return hi(e,!1)}function pi(e,t,n,r,i){var o=Ki(e,t),l=Dl&&o.markedSpans;if(l)for(var s=0;s<l.length;++s){var a=l[s];if(a.marker.collapsed){var u=a.marker.find(0),c=Hl(u.from,n)||ai(a.marker)-ai(i),h=Hl(u.to,r)||ui(a.marker)-ui(i);if(!(c>=0&&0>=h||0>=c&&h>=0)&&(0>=c&&(Hl(u.to,n)>0||a.marker.inclusiveRight&&i.inclusiveLeft)||c>=0&&(Hl(u.from,r)<0||a.marker.inclusiveLeft&&i.inclusiveRight)))return!0}}}function gi(e){for(var t;t=fi(e);)e=t.find(-1,!0).line;return e}function mi(e){for(var t,n;t=di(e);)e=t.find(1,!0).line,(n||(n=[])).push(e);return n}function vi(e,t){var n=Ki(e,t),r=gi(n);return n==r?t:Qi(r)}function yi(e,t){if(t>e.lastLine())return t;var n,r=Ki(e,t);if(!bi(e,r))return t;for(;n=di(r);)r=n.
 find(1,!0).line;return Qi(r)+1}function bi(e,t){var n=Dl&&t.markedSpans;if(n)for(var r,i=0;i<n.length;++i)if(r=n[i],r.marker.collapsed){if(null==r.from)return!0;if(!r.marker.widgetNode&&0==r.from&&r.marker.inclusiveLeft&&xi(e,t,r))return!0}}function xi(e,t,n){if(null==n.to){var r=n.marker.find(1,!0);return xi(e,r.line,Zr(r.line.markedSpans,n.marker))}if(n.marker.inclusiveRight&&n.to==t.text.length)return!0;for(var i,o=0;o<t.markedSpans.length;++o)if(i=t.markedSpans[o],i.marker.collapsed&&!i.marker.widgetNode&&i.from==n.to&&(null==i.to||i.to!=n.from)&&(i.marker.inclusiveLeft||n.marker.inclusiveRight)&&xi(e,t,i))return!0}function wi(e,t,n){eo(t)<(e.curOp&&e.curOp.scrollTop||e.doc.scrollTop)&&Er(e,null,n)}function Ci(e){if(null!=e.height)return e.height;var t=e.doc.cm;if(!t)return 0;if(!_s(document.body,e.node)){var n="position: relative;";e.coverGutter&&(n+="margin-left: -"+t.display.gutters.offsetWidth+"px;"),e.noHScroll&&(n+="width: "+t.display.wrapper.clientWidth+"px;"),qo(t.displa
 y.measure,_o("div",[e.node],null,n))}return e.height=e.node.offsetHeight}function ki(e,t,n,r){var i=new ds(e,n,r),o=e.cm;return o&&i.noHScroll&&(o.display.alignWidgets=!0),Pr(e,t,"widget",function(t){var n=t.widgets||(t.widgets=[]);if(null==i.insertAt?n.push(i):n.splice(Math.min(n.length-1,Math.max(0,i.insertAt)),0,i),i.line=t,o&&!bi(e,t)){var r=eo(t)<e.scrollTop;Zi(t,t.height+Ci(i)),r&&Er(o,null,i.height),o.curOp.forceUpdate=!0}return!0}),i}function Si(e,t,n,r){e.text=t,e.stateAfter&&(e.stateAfter=null),e.styles&&(e.styles=null),null!=e.order&&(e.order=null),li(e),si(e,n);var i=r?r(e):1;i!=e.height&&Zi(e,i)}function Li(e){e.parent=null,li(e)}function Mi(e,t){if(e)for(;;){var n=e.match(/(?:^|\s+)line-(background-)?(\S+)/);if(!n)break;e=e.slice(0,n.index)+e.slice(n.index+n[0].length);var r=n[1]?"bgClass":"textClass";null==t[r]?t[r]=n[2]:new RegExp("(?:^|s)"+n[2]+"(?:$|s)").test(t[r])||(t[r]+=" "+n[2])}return e}function Ti(t,n){if(t.blankLine)return t.blankLine(n);if(t.innerMode){var 
 r=e.innerMode(t,n);return r.mode.blankLine?r.mode.blankLine(r.state):void 0}}function Ni(t,n,r,i){for(var o=0;10>o;o++){i&&(i[0]=e.innerMode(t,r).mode);var l=t.token(n,r);if(n.pos>n.start)return l}throw new Error("Mode "+t.name+" failed to advance stream.")}function Ai(e,t,n,r){function i(e){return{start:h.start,end:h.pos,string:h.current(),type:o||null,state:e?ns(l.mode,c):c}}var o,l=e.doc,s=l.mode;t=mt(l,t);var a,u=Ki(l,t.line),c=Rt(e,t.line,n),h=new us(u.text,e.options.tabSize);for(r&&(a=[]);(r||h.pos<t.ch)&&!h.eol();)h.start=h.pos,o=Ni(s,h,c),r&&a.push(i(!0));return r?a:i()}function Oi(e,t,n,r,i,o,l){var s=n.flattenSpans;null==s&&(s=e.options.flattenSpans);var a,u=0,c=null,h=new us(t,e.options.tabSize),f=e.options.addModeClass&&[null];for(""==t&&Mi(Ti(n,r),o);!h.eol();){if(h.pos>e.options.maxHighlightLength?(s=!1,l&&Hi(e,t,r,h.pos),h.pos=t.length,a=null):a=Mi(Ni(n,h,r,f),o),f){var d=f[0].name;d&&(a="m-"+(a?d+" "+a:d))}if(!s||c!=a){for(;u<h.start;)u=Math.min(h.start,u+5e4),i(u,c)
 ;c=a}h.start=h.pos}for(;u<h.pos;){var p=Math.min(h.pos,u+5e4);i(p,c),u=p}}function Di(e,t,n,r){var i=[e.state.modeGen],o={};Oi(e,t.text,e.doc.mode,n,function(e,t){i.push(e,t)},o,r);for(var l=0;l<e.state.overlays.length;++l){var s=e.state.overlays[l],a=1,u=0;Oi(e,t.text,s.mode,!0,function(e,t){for(var n=a;e>u;){var r=i[a];r>e&&i.splice(a,1,e,i[a+1],r),a+=2,u=Math.min(e,r)}if(t)if(s.opaque)i.splice(n,a-n,e,"cm-overlay "+t),a=n+2;else for(;a>n;n+=2){var o=i[n+1];i[n+1]=(o?o+" ":"")+"cm-overlay "+t}},o)}return{styles:i,classes:o.bgClass||o.textClass?o:null}}function Wi(e,t,n){if(!t.styles||t.styles[0]!=e.state.modeGen){var r=Di(e,t,t.stateAfter=Rt(e,Qi(t)));t.styles=r.styles,r.classes?t.styleClasses=r.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.frontier&&e.doc.frontier++}return t.styles}function Hi(e,t,n,r){var i=e.doc.mode,o=new us(t,e.options.tabSize);for(o.start=o.pos=r||0,""==t&&Ti(i,n);!o.eol()&&o.pos<=e.options.maxHighlightLength;)Ni(i,o,n),o.start=o.pos}function Ei(e,
 t){if(!e||/^\s*$/.test(e))return null;var n=t.addModeClass?ms:gs;return n[e]||(n[e]=e.replace(/\S+/g,"cm-$&"))}function Ii(e,t){var n=_o("span",null,null,ml?"padding-right: .1px":null),r={pre:_o("pre",[n],"CodeMirror-line"),content:n,col:0,pos:0,cm:e,splitSpaces:(pl||ml)&&e.getOption("lineWrapping")};t.measure={};for(var i=0;i<=(t.rest?t.rest.length:0);i++){var o,l=i?t.rest[i-1]:t.line;r.pos=0,r.addToken=zi,Yo(e.display.measure)&&(o=to(l))&&(r.addToken=Bi(r.addToken,o)),r.map=[];var s=t!=e.display.externalMeasured&&Qi(l);Ri(l,r,Wi(e,l,s)),l.styleClasses&&(l.styleClasses.bgClass&&(r.bgClass=$o(l.styleClasses.bgClass,r.bgClass||"")),l.styleClasses.textClass&&(r.textClass=$o(l.styleClasses.textClass,r.textClass||""))),0==r.map.length&&r.map.push(0,0,r.content.appendChild(Xo(e.display.measure))),0==i?(t.measure.map=r.map,t.measure.cache={}):((t.measure.maps||(t.measure.maps=[])).push(r.map),(t.measure.caches||(t.measure.caches=[])).push({}))}return ml&&/\bcm-tab\b/.test(r.content.lastCh
 ild.className)&&(r.content.className="cm-tab-wrap-hack"),Ms(e,"renderLine",e,t.line,r.pre),r.pre.className&&(r.textClass=$o(r.pre.className,r.textClass||"")),r}function Fi(e){var t=_o("span","•","cm-invalidchar");return t.title="\\u"+e.charCodeAt(0).toString(16),t.setAttribute("aria-label",t.title),t}function zi(e,t,n,r,i,o,l){if(t){var s=e.splitSpaces?t.replace(/ {3,}/g,Pi):t,a=e.cm.state.specialChars,u=!1;if(a.test(t))for(var c=document.createDocumentFragment(),h=0;;){a.lastIndex=h;var f=a.exec(t),d=f?f.index-h:t.length-h;if(d){var p=document.createTextNode(s.slice(h,h+d));c.appendChild(pl&&9>gl?_o("span",[p]):p),e.map.push(e.pos,e.pos+d,p),e.col+=d,e.pos+=d}if(!f)break;if(h+=d+1,"	"==f[0]){var g=e.cm.options.tabSize,m=g-e.col%g,p=c.appendChild(_o("span",Ao(m),"cm-tab"));p.setAttribute("role","presentation"),p.setAttribute("cm-text","	"),e.col+=m}else{var p=e.cm.options.specialCharPlaceholder(f[0]);p.setAttribute("cm-text",f[0]),c.appendChild(pl&&9>gl?_o("span",[p]):p),e.col+=1}
 e.map.push(e.pos,e.pos+1,p),e.pos++}else{e.col+=t.length;var c=document.createTextNode(s);e.map.push(e.pos,e.pos+t.length,c),pl&&9>gl&&(u=!0),e.pos+=t.length}if(n||r||i||u||l){var v=n||"";r&&(v+=r),i&&(v+=i);var y=_o("span",[c],v,l);return o&&(y.title=o),e.content.appendChild(y)}e.content.appendChild(c)}}function Pi(e){for(var t=" ",n=0;n<e.length-2;++n)t+=n%2?" ":" ";return t+=" "}function Bi(e,t){return function(n,r,i,o,l,s,a){i=i?i+" cm-force-border":"cm-force-border";for(var u=n.pos,c=u+r.length;;){for(var h=0;h<t.length;h++){var f=t[h];if(f.to>u&&f.from<=u)break}if(f.to>=c)return e(n,r,i,o,l,s,a);e(n,r.slice(0,f.to-u),i,o,null,s,a),o=null,r=r.slice(f.to-u),u=f.to}}}function _i(e,t,n,r){var i=!r&&n.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!r&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",n.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t}function Ri(e,t,n){var r=
 e.markedSpans,i=e.text,o=0;if(r)for(var l,s,a,u,c,h,f,d=i.length,p=0,g=1,m="",v=0;;){if(v==p){a=u=c=h=s="",f=null,v=1/0;for(var y=[],b=0;b<r.length;++b){var x=r[b],w=x.marker;"bookmark"==w.type&&x.from==p&&w.widgetNode?y.push(w):x.from<=p&&(null==x.to||x.to>p||w.collapsed&&x.to==p&&x.from==p)?(null!=x.to&&x.to!=p&&v>x.to&&(v=x.to,u=""),w.className&&(a+=" "+w.className),w.css&&(s=w.css),w.startStyle&&x.from==p&&(c+=" "+w.startStyle),w.endStyle&&x.to==v&&(u+=" "+w.endStyle),w.title&&!h&&(h=w.title),w.collapsed&&(!f||ci(f.marker,w)<0)&&(f=x)):x.from>p&&v>x.from&&(v=x.from)}if(f&&(f.from||0)==p){if(_i(t,(null==f.to?d+1:f.to)-p,f.marker,null==f.from),null==f.to)return;f.to==p&&(f=!1)}if(!f&&y.length)for(var b=0;b<y.length;++b)_i(t,0,y[b])}if(p>=d)break;for(var C=Math.min(d,v);;){if(m){var k=p+m.length;if(!f){var S=k>C?m.slice(0,C-p):m;t.addToken(t,S,l?l+a:a,c,p+S.length==v?u:"",h,s)}if(k>=C){m=m.slice(C-p),p=C;break}p=k,c=""}m=i.slice(o,o=n[g++]),l=Ei(n[g++],t.cm.options)}}else for(var g
 =1;g<n.length;g+=2)t.addToken(t,i.slice(o,o=n[g]),Ei(n[g+1],t.cm.options))}function qi(e,t){return 0==t.from.ch&&0==t.to.ch&&""==Oo(t.text)&&(!e.cm||e.cm.options.wholeLineUpdateBefore)}function Ui(e,t,n,r){function i(e){return n?n[e]:null}function o(e,n,i){Si(e,n,i,r),wo(e,"change",e,t)}function l(e,t){for(var n=e,o=[];t>n;++n)o.push(new ps(u[n],i(n),r));return o}var s=t.from,a=t.to,u=t.text,c=Ki(e,s.line),h=Ki(e,a.line),f=Oo(u),d=i(u.length-1),p=a.line-s.line;if(t.full)e.insert(0,l(0,u.length)),e.remove(u.length,e.size-u.length);else if(qi(e,t)){var g=l(0,u.length-1);o(h,h.text,d),p&&e.remove(s.line,p),g.length&&e.insert(s.line,g)}else if(c==h)if(1==u.length)o(c,c.text.slice(0,s.ch)+f+c.text.slice(a.ch),d);else{var g=l(1,u.length-1);g.push(new ps(f+c.text.slice(a.ch),d,r)),o(c,c.text.slice(0,s.ch)+u[0],i(0)),e.insert(s.line+1,g)}else if(1==u.length)o(c,c.text.slice(0,s.ch)+u[0]+h.text.slice(a.ch),i(0)),e.remove(s.line+1,p);else{o(c,c.text.slice(0,s.ch)+u[0],i(0)),o(h,f+h.text.slice
 (a.ch),d);var g=l(1,u.length-1);p>1&&e.remove(s.line+1,p-1),e.insert(s.line+1,g)}wo(e,"change",e,t)}function Gi(e){this.lines=e,this.parent=null;for(var t=0,n=0;t<e.length;++t)e[t].parent=this,n+=e[t].height;this.height=n}function $i(e){this.children=e;for(var t=0,n=0,r=0;r<e.length;++r){var i=e[r];t+=i.chunkSize(),n+=i.height,i.parent=this}this.size=t,this.height=n,this.parent=null}function ji(e,t,n){function r(e,i,o){if(e.linked)for(var l=0;l<e.linked.length;++l){var s=e.linked[l];if(s.doc!=i){var a=o&&s.sharedHist;(!n||a)&&(t(s.doc,a),r(s.doc,e,a))}}}r(e,null,!0)}function Vi(e,t){if(t.cm)throw new Error("This document is already in use.");e.doc=t,t.cm=e,l(e),n(e),e.options.lineWrapping||f(e),e.options.mode=t.modeOption,In(e)}function Ki(e,t){if(t-=e.first,0>t||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var i=n.children[r],o=i.chunkSize();if(o>t){n=i;break}t-=o}return n.lines[t]}function Xi(e,t,n){var r=[]
 ,i=t.line;return e.iter(t.line,n.line+1,function(e){var o=e.text;i==n.line&&(o=o.slice(0,n.ch)),i==t.line&&(o=o.slice(t.ch)),r.push(o),++i}),r}function Yi(e,t,n){var r=[];return e.iter(t,n,function(e){r.push(e.text)}),r}function Zi(e,t){var n=t-e.height;if(n)for(var r=e;r;r=r.parent)r.height+=n}function Qi(e){if(null==e.parent)return null;for(var t=e.parent,n=Do(t.lines,e),r=t.parent;r;t=r,r=r.parent)for(var i=0;r.children[i]!=t;++i)n+=r.children[i].chunkSize();return n+t.first}function Ji(e,t){var n=e.first;e:do{for(var r=0;r<e.children.length;++r){var i=e.children[r],o=i.height;if(o>t){e=i;continue e}t-=o,n+=i.chunkSize()}return n}while(!e.lines);for(var r=0;r<e.lines.length;++r){var l=e.lines[r],s=l.height;if(s>t)break;t-=s}return n+r}function eo(e){e=gi(e);for(var t=0,n=e.parent,r=0;r<n.lines.length;++r){var i=n.lines[r];if(i==e)break;t+=i.height}for(var o=n.parent;o;n=o,o=n.parent)for(var r=0;r<o.children.length;++r){var l=o.children[r];if(l==n)break;t+=l.height}return t}functi
 on to(e){var t=e.order;return null==t&&(t=e.order=Js(e.text)),t}function no(e){this.done=[],this.undone=[],this.undoDepth=1/0,this.lastModTime=this.lastSelTime=0,this.lastOp=this.lastSelOp=null,this.lastOrigin=this.lastSelOrigin=null,this.generation=this.maxGeneration=e||1}function ro(e,t){var n={from:V(t.from),to:Vl(t),text:Xi(e,t.from,t.to)};return co(e,n,t.from.line,t.to.line+1),ji(e,function(e){co(e,n,t.from.line,t.to.line+1)},!0),n}function io(e){for(;e.length;){var t=Oo(e);if(!t.ranges)break;e.pop()}}function oo(e,t){return t?(io(e.done),Oo(e.done)):e.done.length&&!Oo(e.done).ranges?Oo(e.done):e.done.length>1&&!e.done[e.done.length-2].ranges?(e.done.pop(),Oo(e.done)):void 0}function lo(e,t,n,r){var i=e.history;i.undone.length=0;var o,l=+new Date;if((i.lastOp==r||i.lastOrigin==t.origin&&t.origin&&("+"==t.origin.charAt(0)&&e.cm&&i.lastModTime>l-e.cm.options.historyEventDelay||"*"==t.origin.charAt(0)))&&(o=oo(i,i.lastOp==r))){var s=Oo(o.changes);0==Hl(t.from,t.to)&&0==Hl(t.from,s
 .to)?s.to=Vl(t):o.changes.push(ro(e,t))}else{var a=Oo(i.done);for(a&&a.ranges||uo(e.sel,i.done),o={changes:[ro(e,t)],generation:i.generation},i.done.push(o);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(n),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=l,i.lastOp=i.lastSelOp=r,i.lastOrigin=i.lastSelOrigin=t.origin,s||Ms(e,"historyAdded")}function so(e,t,n,r){var i=t.charAt(0);return"*"==i||"+"==i&&n.ranges.length==r.ranges.length&&n.somethingSelected()==r.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}function ao(e,t,n,r){var i=e.history,o=r&&r.orig

<TRUNCATED>

[34/50] [abbrv] allura git commit: [#7925] Speed up diff processing on commit browser page

Posted by he...@apache.org.
[#7925] Speed up diff processing on commit browser page


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e252f5e1
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e252f5e1
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e252f5e1

Branch: refs/heads/hs/7925
Commit: e252f5e1bf907e8fa886bb8fdffb0f05bc291df0
Parents: 032c2ed
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Thu Jul 16 15:02:55 2015 -0400
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:35 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py  |  3 ++-
 Allura/allura/model/repository.py        |  6 ++++++
 Allura/allura/templates/repo/commit.html | 14 ++++++++------
 3 files changed, 16 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e252f5e1/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 2b9ae89..5d03f64 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -564,7 +564,8 @@ class CommitBrowser(BaseController):
                                              default=self.DEFAULT_PAGE_LIMIT)
         diffs = self._commit.paged_diffs(start=start, end=start + limit)
         result['artifacts'] = [
-            (t, f, 'blob' if tree.get_blob_by_path(f) else 'tree')
+            (t, f, 'blob' if tree.get_blob_by_path(f) else 'tree',
+            tree.get_blob_by_path(f) and tree.get_blob_by_path(f).is_text)
             for t in ('added', 'removed', 'changed', 'copied')
             for f in diffs[t]]
         count = diffs['total']

http://git-wip-us.apache.org/repos/asf/allura/blob/e252f5e1/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index b3c60b7..7bc36c1 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -1520,6 +1520,12 @@ class Blob(object):
         return self._content_type_encoding[0]
 
     @LazyProperty
+    def is_text(self):
+        """Return true if this blob is text."""
+
+        return self.content_type.startswith("text")
+
+    @LazyProperty
     def content_encoding(self):
         return self._content_type_encoding[1]
 

http://git-wip-us.apache.org/repos/asf/allura/blob/e252f5e1/Allura/allura/templates/repo/commit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/commit.html b/Allura/allura/templates/repo/commit.html
index 4870332..f029f52 100644
--- a/Allura/allura/templates/repo/commit.html
+++ b/Allura/allura/templates/repo/commit.html
@@ -113,7 +113,7 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
 {{c.page_list.display(page=page, limit=limit, count=count)}}
 <table>
   <tbody>
-    {% for type, file, _ in artifacts %}
+    {% for type, file, _, _ in artifacts %}
     <tr>
         <td>{{ type }}</td>
         <td><a href="#diff-{{loop.index}}">
@@ -128,9 +128,10 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
   </tbody>
 </table>
 
-{% for type, file, obj_type in artifacts %}
-        <div class="inline-diff">
-            <h6>
+    {% for type, file, obj_type, is_text in artifacts %}
+        {% if is_text %}
+            <div class="inline-diff">
+                <h6>
             {% if type in ('added', 'changed') %}
                 {% if obj_type == 'tree' %}
                     <a href="{{commit.url()}}tree/{{h.urlquote(h.really_unicode(file))}}">{{h.really_unicode(file)}}</a>
@@ -169,6 +170,7 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
                 {% endif %}
             </div>
         </div>
-{% endfor %}
-{{c.page_list.display(page=page, limit=limit, count=count)}}
+        {% endif %}
+    {% endfor %}
+    {{ c.page_list.display(page=page, limit=limit, count=count) }}
 {% endblock %}


[43/50] [abbrv] allura git commit: [#7925] add renamed files to template used by "Browse Commits" page

Posted by he...@apache.org.
[#7925] add renamed files to template used by "Browse Commits" page


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9835504d
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9835504d
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9835504d

Branch: refs/heads/hs/7925
Commit: 9835504d7f5e0fd68195b92ba5f66e65f844c02f
Parents: 3a8037c
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 20:36:07 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:37 2015 -0400

----------------------------------------------------------------------
 Allura/allura/templates/repo/commit_basic.html | 9 +++++++++
 1 file changed, 9 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/9835504d/Allura/allura/templates/repo/commit_basic.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/commit_basic.html b/Allura/allura/templates/repo/commit_basic.html
index f1625ca..e4ec126 100644
--- a/Allura/allura/templates/repo/commit_basic.html
+++ b/Allura/allura/templates/repo/commit_basic.html
@@ -46,6 +46,15 @@
         <a href="{{commit.url()}}tree/{{h.really_unicode(diff.new)}}">{{h.really_unicode(diff.new)}}</a>
       </td>
     </tr>
+    {% endfor %}{% for diff in commit.diffs.renamed %}
+    <tr>
+      <td>rename</td>
+      <td>
+        <a href="{{prev[0].url()}}tree/{{h.really_unicode(diff.old)}}">{{h.really_unicode(diff.old)}}</a>
+        <br/>to<br/>
+        <a href="{{commit.url()}}tree/{{h.really_unicode(diff.new)}}">{{h.really_unicode(diff.new)}}</a>
+      </td>
+    </tr>
     {% endfor %}
   </tbody>
 </table>


[39/50] [abbrv] allura git commit: [#7925] simplify and de-bug git output processing by using a new var, no in-place updates to 'files'

Posted by he...@apache.org.
[#7925] simplify and de-bug git output processing by using a new var, no in-place updates to 'files'


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/5adbb285
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/5adbb285
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/5adbb285

Branch: refs/heads/hs/7925
Commit: 5adbb2858dd0f5ac189bc10dc85530e481380cba
Parents: 787ee90
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Jul 31 16:12:23 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:36 2015 -0400

----------------------------------------------------------------------
 ForgeGit/forgegit/model/git_repo.py | 74 ++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5adbb285/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index ece0d6c..9462087 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -642,9 +642,9 @@ class GitImplementation(M.RepositoryImplementation):
             max_count=1).splitlines()[1:]
 
     def paged_diffs(self, commit_id, start=0, end=None):
-        result = {'added': [], 'removed': [], 'changed': [], 'copied': [], 'renamed': [], 'total': 0}
+        result = {'added': [], 'removed': [], 'changed': [], 'copied': [], 'renamed': []}
 
-        files = self._git.git.diff_tree(
+        cmd_output = self._git.git.diff_tree(
             '--no-commit-id',
             '--find-renames',
             '--find-copies',
@@ -656,39 +656,49 @@ class GitImplementation(M.RepositoryImplementation):
             '-z',  # don't escape filenames and use \x00 as fields delimiter
             commit_id).split('\x00')[:-1]
 
-        result['total'] = len(files) / 2
-        x = 0
-        while x < len(files):
-            try:
-                if files[x].startswith("R") or files[x].startswith("C"):
-                    change_list = result['renamed'] if files[x].startswith("R") else result['copied']
-                    ratio = float(files[x][1:4]) / 100.0
-                    change_list.append({
-                        'new': h.really_unicode(files[x + 2]),
-                        'old': h.really_unicode(files[x + 1]),
-                        'ratio': ratio,
-                        'diff': '',
-                    })
-                    del files[x:x+3]
-                    x += 3
-                    result['total'] -= 1
-                else:
-                    x += 2
-            except IndexError:
-                break
+        ''' cmd_output will be like:
+        [
+        'A',
+        'filename',
+        'D',
+        'another filename',
+        'M',
+        'po',
+        'R100',
+        'po/sr.po',
+        'po/sr_Latn.po',
+        ]
+        '''
 
-        files = [(files[i], h.really_unicode(files[i + 1]))
-                 for i in xrange(0, result['total'] + 1, 2)]
+        x = 0
+        files = []
+        while x < len(cmd_output):
+            status = cmd_output[x][0]
+            if status in ('R', 'C'):
+                # TODO: make sure we have a test for this
+                ratio = float(cmd_output[x][1:4]) / 100.0
+                files.append((status, {
+                    'new': h.really_unicode(cmd_output[x + 2]),
+                    'old': h.really_unicode(cmd_output[x + 1]),
+                    'ratio': ratio,
+                    'diff': '',
+                }))
+                x += 3
+            else:
+                files.append((status, h.really_unicode(cmd_output[x+1])))
+                x += 2
 
-        # files = [('A', u'filename'), ('D', u'another filename'), ...]
         for status, name in files[start:end]:
-            if status == 'A':
-                result['added'].append(name)
-            elif status == 'D':
-                result['removed'].append(name)
-            elif status == 'M':
-                result['changed'].append(name)
-
+            change_list = {
+                'R': result['renamed'],
+                'C': result['copied'],
+                'A': result['added'],
+                'D': result['removed'],
+                'M': result['changed']
+            }[status]
+            change_list.append(name)
+
+        result['total'] = len(files)
         return result
 
     @contextmanager


[30/50] [abbrv] allura git commit: [#7950] avoid conflicting height declarations for wiki editor

Posted by he...@apache.org.
[#7950] avoid conflicting height declarations for wiki editor


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/8a226bd5
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/8a226bd5
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/8a226bd5

Branch: refs/heads/hs/7925
Commit: 8a226bd59b0a8c03c8af9848403285b67cc4b886
Parents: d884945
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Aug 7 14:10:49 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri Aug 7 14:10:49 2015 +0000

----------------------------------------------------------------------
 ForgeWiki/forgewiki/templates/wiki/page_edit.html | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8a226bd5/ForgeWiki/forgewiki/templates/wiki/page_edit.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_edit.html b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
index fa0e95e..4e9584b 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_edit.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
@@ -26,8 +26,7 @@
 {% block extra_css %}
 <style type="text/css">
   .markdown_edit .CodeMirror {
-    height: auto;
-    min-height: 600px;
+    height: 500px;  /* match max-height in markitup_sf.css */
   }
 </style>
 {% endblock %}


[08/50] [abbrv] allura git commit: [#7897] ticket:820 Remove custom focus handler

Posted by he...@apache.org.
[#7897] ticket:820 Remove custom focus handler

This handler breaks text selection on when preview is enabled and we
don't really need it, anyway.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/19b06830
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/19b06830
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/19b06830

Branch: refs/heads/hs/7925
Commit: 19b06830c84697df2629eeadbab03aa88bb1f53c
Parents: 78c0842
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Jul 14 17:07:06 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 14:23:56 2015 +0300

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/js/sf_markitup.js | 3 ---
 1 file changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/19b06830/Allura/allura/lib/widgets/resources/js/sf_markitup.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/sf_markitup.js b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
index 4162c9a..1dfdf4e 100644
--- a/Allura/allura/lib/widgets/resources/js/sf_markitup.js
+++ b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
@@ -54,9 +54,6 @@ $(window).load(function() {
             });
             editor.render();
 
-            // focus editor by clicking anywhere on it, not only on the first few lines
-            $('.CodeMirror').click(function () { this.CodeMirror.focus(); });
-
             function show_help(editor) {
               $help_contents.html('Loading...');
               $.get($help_contents.attr('data-url'), function (data) {


[10/50] [abbrv] allura git commit: [#7897] ticket:828 Decrease margin

Posted by he...@apache.org.
[#7897] ticket:828 Decrease margin


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/465f2254
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/465f2254
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/465f2254

Branch: refs/heads/hs/7925
Commit: 465f225418ad9ade0053f794c021d030abe60715
Parents: d3a99a4
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Jul 27 16:09:41 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 27 16:09:41 2015 +0300

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/465f2254/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index a188133..ca78000 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -2642,7 +2642,7 @@ div.attachment_thumb .file_type span {
   float: none;
   padding-left: 1em;
   list-style-type: disc;
-  margin-bottom: 20px !important;
+  margin-bottom: 5px !important;
 }
 #comment .edit_post_form ul,
 #comment .reply_post_form ul {
@@ -3018,6 +3018,9 @@ td.code {
     width:100%;
 }
 
+div.codehilite {
+  margin-bottom: 5px;
+}
 div.codehilite pre {
     padding-left: 0px;
     padding-top:10px;


[21/50] [abbrv] allura git commit: [#7947] match case of beautifulsoup4, with pypi

Posted by he...@apache.org.
[#7947] match case of beautifulsoup4, with pypi


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/0015f479
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/0015f479
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/0015f479

Branch: refs/heads/hs/7925
Commit: 0015f4792248a537079dfa4f04f00ce85f767cee
Parents: cc5f2ac
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Aug 3 21:47:05 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Aug 3 21:47:05 2015 +0000

----------------------------------------------------------------------
 requirements.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0015f479/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index d327584..0c96317 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
 ActivityStream==0.2.0
 BeautifulSoup==3.2.0
-BeautifulSoup4==4.4.0
+beautifulsoup4==4.4.0
 Beaker==1.6.4
 chardet==1.0.1
 colander==0.9.3


[33/50] [abbrv] allura git commit: [#7925] Refactor and improve the diff processing

Posted by he...@apache.org.
[#7925] Refactor and improve the diff processing


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/7f738bdf
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/7f738bdf
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/7f738bdf

Branch: refs/heads/hs/7925
Commit: 7f738bdfbb93e78d8d557f8b60fb1965ce9e67ce
Parents: 7eeb0dd
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Mon Jul 27 16:06:28 2015 -0400
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:35 2015 -0400

----------------------------------------------------------------------
 Allura/allura/lib/custom_middleware.py |  4 --
 Allura/allura/model/repository.py      | 67 +----------------------------
 ForgeGit/forgegit/model/git_repo.py    | 51 +++++++++++++++-------
 ForgeSVN/forgesvn/model/svn.py         | 17 +++++---
 4 files changed, 47 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/7f738bdf/Allura/allura/lib/custom_middleware.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/custom_middleware.py b/Allura/allura/lib/custom_middleware.py
index e56a530..1938e51 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -322,10 +322,6 @@ class AlluraTimerMiddleware(TimerMiddleware):
             Timer('urlopen', urllib2, 'urlopen'),
             Timer('base_repo_tool.{method_name}',
                   allura.model.repository.RepositoryImplementation, 'last_commit_ids'),
-            Timer('_diffs_copied', allura.model.repository.Commit, '_diffs_copied'),
-            Timer(
-                'sequencematcher.{method_name}', allura.model.repository.SequenceMatcher,
-                'ratio', 'quick_ratio', 'real_quick_ratio'),
             Timer('unified_diff', allura.model.repository, 'unified_diff'),
         ] + [Timer('sidebar', ep.load(), 'sidebar_menu') for ep in tool_entry_points]
 

http://git-wip-us.apache.org/repos/asf/allura/blob/7f738bdf/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 5fe2ba9..636d10c 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -1168,78 +1168,15 @@ class Commit(RepoObject, ActivityObject):
 
     def paged_diffs(self, start=0, end=None):
         diffs = self.repo.paged_diffs(self._id, start, end)
-        if not diffs.get('copied'):
-            diffs['copied'] = []
-        copied = self._diffs_copied(diffs['added'], diffs['removed'])
-        diffs['copied'].extend(copied)
+
         return Object(
             added=sorted(diffs['added']),
             removed=sorted(diffs['removed']),
             changed=sorted(diffs['changed']),
             copied=sorted(diffs['copied']),
+            renamed=sorted(diffs['renamed']),
             total=diffs['total'])
 
-    def _diffs_copied(self, added, removed):
-        '''Return list with file renames diffs.
-
-        Will change `added` and `removed` lists also.
-        '''
-        def _blobs_similarity(removed_blob, added):
-            best = dict(ratio=0, name='', blob=None)
-            for added_name in added:
-                added_blob = self.tree.get_obj_by_path(added_name)
-                if not isinstance(added_blob, Blob):
-                    continue
-                diff = SequenceMatcher(None, removed_blob.text,
-                                       added_blob.text)
-                ratio = diff.quick_ratio()
-                if ratio > best['ratio']:
-                    best['ratio'] = ratio
-                    best['name'] = added_name
-                    best['blob'] = added_blob
-
-                if ratio == 1:
-                    break  # we'll won't find better similarity than 100% :)
-
-            if best['ratio'] > DIFF_SIMILARITY_THRESHOLD:
-                diff = ''
-                if best['ratio'] < 1:
-                    added_blob = best['blob']
-                    rpath = ('a' + removed_blob.path()).encode('utf-8')
-                    apath = ('b' + added_blob.path()).encode('utf-8')
-                    diff = ''.join(unified_diff(list(removed_blob),
-                                                list(added_blob),
-                                                rpath, apath))
-                return dict(new=best['name'],
-                            ratio=best['ratio'], diff=diff)
-
-        def _trees_similarity(removed_tree, added):
-            for added_name in added:
-                added_tree = self.tree.get_obj_by_path(added_name)
-                if not isinstance(added_tree, Tree):
-                    continue
-                if removed_tree._id == added_tree._id:
-                    return dict(new=added_name,
-                                ratio=1, diff='')
-
-        if not removed:
-            return []
-        copied = []
-        prev_commit = self.get_parent()
-        for removed_name in removed[:]:
-            removed_blob = prev_commit.tree.get_obj_by_path(removed_name)
-            rename_info = None
-            if isinstance(removed_blob, Blob):
-                rename_info = _blobs_similarity(removed_blob, added)
-            elif isinstance(removed_blob, Tree):
-                rename_info = _trees_similarity(removed_blob, added)
-            if rename_info is not None:
-                rename_info['old'] = removed_name
-                copied.append(rename_info)
-                removed.remove(rename_info['old'])
-                added.remove(rename_info['new'])
-        return copied
-
     def get_path(self, path, create=True):
         path = path.lstrip('/')
         parts = path.split('/')

http://git-wip-us.apache.org/repos/asf/allura/blob/7f738bdf/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 9549fa6..9a8549a 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -642,36 +642,55 @@ class GitImplementation(M.RepositoryImplementation):
             max_count=1).splitlines()[1:]
 
     def paged_diffs(self, commit_id, start=0, end=None):
-        added, removed, changed = [], [], []
+        result = {'added': [], 'removed': [], 'changed': [], 'copied': [], 'renamed': [], 'total': 0}
+
         files = self._git.git.diff_tree(
             '--no-commit-id',
+            '--find-renames',
+            '--find-copies',
             '--name-status',
-            '--no-renames',
+            '--no-abbrev',
             '--root',
-            # show tree entry itself as well as subtrees (Commit.added_paths
-            # relies on this)
+            '--find-copies-harder',
+            # show tree entry itself as well as subtrees (Commit.added_paths relies on this)
             '-t',
             '-z',  # don't escape filenames and use \x00 as fields delimiter
             commit_id).split('\x00')[:-1]
 
-        total = len(files) / 2
-        files = [(files[i], h.really_unicode(files[i+1]))
-                 for i in xrange(0, len(files), 2)]
+        result['total'] = len(files) / 2
+        x = 0
+        while x < len(files):
+            try:
+                if files[x].startswith("R") or files[x].startswith("C"):
+                    change_list = result['renamed'] if files[x].startswith("R") else result['copied']
+                    ratio = float(files[x][1:4]) / 100.0
+                    change_list.append({
+                        'new': h.really_unicode(files[x + 2]),
+                        'old': h.really_unicode(files[x + 1]),
+                        'ratio': ratio,
+                        'diff': '',
+                    })
+                    del files[x:x+3]
+                    x += 3
+                    result['total'] -= 1
+                else:
+                    x += 2
+            except IndexError:
+                break
+
+        files = [(files[i], h.really_unicode(files[i + 1]))
+                 for i in xrange(0, result['total'] + 1, 2)]
 
         # files = [('A', u'filename'), ('D', u'another filename'), ...]
         for status, name in files[start:end]:
             if status == 'A':
-                added.append(name)
+                result['added'].append(name)
             elif status == 'D':
-                removed.append(name)
+                result['removed'].append(name)
             elif status == 'M':
-                changed.append(name)
-        return {
-            'added': added,
-            'removed': removed,
-            'changed': changed,
-            'total': total,
-        }
+                result['changed'].append(name)
+
+        return result
 
     @contextmanager
     def _shared_clone(self, from_path):

http://git-wip-us.apache.org/repos/asf/allura/blob/7f738bdf/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index cd410e3..f43f536 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -781,13 +781,7 @@ class SVNImplementation(M.RepositoryImplementation):
         return []
 
     def paged_diffs(self, commit_id, start=0, end=None):
-        result = {
-            'added': [],
-            'removed': [],
-            'changed': [],
-            'copied': [],
-            'total': 0,
-        }
+        result = {'added': [], 'removed': [], 'changed': [], 'copied': [], 'renamed': [], 'total': 0}
         rev = self._revision(commit_id)
         try:
             log_info = self._svn.log(
@@ -822,6 +816,15 @@ class SVNImplementation(M.RepositoryImplementation):
                 # svn add aaa.txt
                 # svn commit -m "Replace aaa.txt"
                 result['changed'].append(h.really_unicode(p.path))
+
+        for r in result['copied']:
+            if r['old'] in result['removed'][:]:
+                result['removed'].remove(r['old'])
+                result['copied'].remove(r)
+                result['renamed'].append(r)
+            if r['new'] in result['added']:
+                result['added'].remove(r['new'])
+
         return result
 
 Mapper.compile_all()


[29/50] [abbrv] allura git commit: [#7950] set a max height to the markdown editor

Posted by he...@apache.org.
[#7950] set a max height to the markdown editor


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d884945e
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d884945e
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d884945e

Branch: refs/heads/hs/7925
Commit: d884945e3d68596f0e28c1a0502273461e956046
Parents: dc857c5
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Aug 6 17:14:34 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Aug 6 17:14:34 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/css/markitup_sf.css | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d884945e/Allura/allura/lib/widgets/resources/css/markitup_sf.css
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/css/markitup_sf.css b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
index 9712461..03822f4 100644
--- a/Allura/allura/lib/widgets/resources/css/markitup_sf.css
+++ b/Allura/allura/lib/widgets/resources/css/markitup_sf.css
@@ -24,12 +24,14 @@
 }
 .markdown_edit .CodeMirror {
   min-height: 60px;
+  height: auto;
   border-bottom: none;
   border-bottom-left-radius: 0;
   border-bottom-right-radius: 0;
 }
 .markdown_edit .CodeMirror-scroll {
   min-height: 60px;
+  max-height: 500px;
 }
 .markdown_edit .editor-statusbar {
   border: 1px solid #ddd;


[46/50] [abbrv] allura git commit: [#7925] more info if file was changed during copy/rename. Don't show diff links if no diff is being displayed

Posted by he...@apache.org.
[#7925] more info if file was changed during copy/rename.  Don't show diff links if no diff is being displayed


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/96391122
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/96391122
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/96391122

Branch: refs/heads/hs/7925
Commit: 963911220644208590b3b767bc3753aececc51e0
Parents: 1919ec0
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Aug 4 14:52:57 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Mon Aug 10 09:38:37 2015 -0400

----------------------------------------------------------------------
 Allura/allura/templates/repo/commit.html | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/96391122/Allura/allura/templates/repo/commit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/commit.html b/Allura/allura/templates/repo/commit.html
index adf57b2..7678a32 100644
--- a/Allura/allura/templates/repo/commit.html
+++ b/Allura/allura/templates/repo/commit.html
@@ -116,7 +116,9 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
   <tbody>
     {% for type, file, _, _ in artifacts %}
     <tr>
-        <td>{{ type }}</td>
+        <td>{{ type }}
+            {% if type in ('copied', 'renamed') and file.ratio != 1 %}(with changes){% endif %}
+        </td>
         <td><a href="#diff-{{loop.index}}">
             {% if type == 'copied' %}
               {{ '%s -> %s' % (h.really_unicode(file.old), h.really_unicode(file.new)) }}
@@ -137,7 +139,7 @@ Commit <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(
             {% if type in ('added', 'changed') %}
                 {% set file_url = commit.url() + 'tree/' + h.urlquote(h.really_unicode(file)) %}
                 <a href="{{ file_url }}">{{h.really_unicode(file)}}</a>
-                {% if obj_type != 'tree' %}
+                {% if obj_type != 'tree' and is_text %}
                     {% set diff_url = file_url + '?barediff=' + (prev[0]._id if prev else '') %}
                     <a class="commit-diff-link" href="{{ diff_url.replace('?barediff=', '?diff=') }}">Diff</a>
                     <a class="commit-diff-link switch-diff-format-link" data-diformat="{{session.diformat}}" data-diffid="diff-{{loop.index}}" href="{{ diff_url }}">Switch to {{'unified' if session.diformat == 'sidebyside' else 'side-by-side'}} view</a>


[15/50] [abbrv] allura git commit: [#7942] require post for removing a custom group

Posted by he...@apache.org.
[#7942] require post for removing a custom group


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/7075554e
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/7075554e
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/7075554e

Branch: refs/heads/hs/7925
Commit: 7075554e79c67fd988dbfbef7be6d51eb485cecf
Parents: 8f5dd48
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Jul 30 14:54:48 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 30 14:54:48 2015 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py        | 1 +
 Allura/allura/public/nf/js/project_groups.js | 6 ++++--
 2 files changed, 5 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/7075554e/Allura/allura/ext/admin/admin_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 5bde57c..ec61edb 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -1036,6 +1036,7 @@ class GroupsController(BaseController):
 
     @without_trailing_slash
     @expose()
+    @require_post()
     @h.vardec
     def delete_group(self, group_name, **kw):
         role = M.ProjectRole.by_name(group_name)

http://git-wip-us.apache.org/repos/asf/allura/blob/7075554e/Allura/allura/public/nf/js/project_groups.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/project_groups.js b/Allura/allura/public/nf/js/project_groups.js
index a4c9ab9..99ecd12 100644
--- a/Allura/allura/public/nf/js/project_groups.js
+++ b/Allura/allura/public/nf/js/project_groups.js
@@ -43,8 +43,10 @@ $(function() {
   $('a.delete_group').click(function(evt){
     evt.preventDefault();
     var link = this;
-    if(confirm("Are you sure you want to remove the group? All users and groups in the group will lose its permissions.")){
-      $.get(link.href, function (data) {
+    var csrf = $.cookie('_session_id');
+    var data = {_session_id: csrf};
+    if(confirm("Are you sure you want to remove the group? All users and groups in the group will lose their permissions.")){
+      $.post(link.href, data, function(resp) {
         $(link).closest('tr').hide('fast');
       });
     }