text:
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Webdiyer.WebControls.Mvc;

namespace MvcPager.Tests
{
    [TestClass]
    public class HtmlPagerTest
    {
        private const string AppPathModifier = TestHelper.AppPathModifier;
        private PagedList<int> _testList;
        private HtmlHelper _htmlHelper;
        const string BaseLink = AppPathModifier + "/mvcpager/test";

        [TestInitialize]
        public void Init()
        {
            _testList = new PagedList<int>(Enumerable.Range(1, 88).ToList(), 1, 8);
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }

        [TestMethod]
        public void PagerOptions_MaximumPageNumberIs8_ShouldGenerateCorrectHtml()
        {
            _testList.PageSize = 5;
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id",
                                                       MaximumPageNumber = 8,RouteName = "Default"
                                                   });
            string htmlStr = html.ToHtmlString();
            const string linkFormat = "{1}";
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"8\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("FirstPrev1");
            for (int i = 2; i <= 8; i++)
            {
                    sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 8, "Last");
            sb.Append("
");
            sb.Append(TestHelper.CopyrightText);
            Assert.AreEqual(htmlStr,sb.ToString());
        }

        [TestMethod]
        public void PagerOptions_AlwaysShowFirstLastPageNumberWithCurrentPageIndexIs12_ShouldGenerateCorrectHtml()
        {
            _testList.PageSize = 2;
            _testList.CurrentPageIndex = 12;
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id", AlwaysShowFirstLastPageNumber = true});
            string htmlStr = html.ToHtmlString();
            const string linkFormat = "{1}";
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-currentpage=\"12\"", "data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"44\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First");
            sb.AppendFormat(linkFormat, 11, "Prev");
            sb.Append("1");
            sb.AppendFormat(linkFormat, 6, "...");
            for (int i = 7; i <= 16; i++)
            {
                if (i == 12)
                    sb.Append(i);
                else
                {
                    sb.AppendFormat(linkFormat, i, i);
                }
            }
            sb.AppendFormat(linkFormat, 17, "...");
            sb.AppendFormat(linkFormat, 44, "44");
            sb.AppendFormat(linkFormat, 13, "Next");
            sb.AppendFormat(linkFormat, 44, "Last");
            sb.Append("
");
            sb.Append(TestHelper.CopyrightText);
            Assert.AreEqual(htmlStr, sb.ToString());
        }

        [TestMethod]
        public void PagerOptions_MaximumPageIndexItemsIs6_ShouldGenerateCorrectHtml()
        {
            _testList.PageSize = 5;
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetPageIndexParameterName("id").SetPageIndexBoxId("pib").SetMaximumPageIndexItems(6));
            string htmlStr = html.ToHtmlString();
            var attrs = new[]
            {
                "data-maxitems=\"6\"","data-pageindexbox=\"#pib\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"18\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            var sb = new StringBuilder("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            StringAssert.Contains(htmlStr,sb.ToString());
        }

        [TestMethod]
        public void PagerOptions_PageIndexErrorMessage_ShouldReturnCorrectString()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetPageIndexParameterName("id").SetPageIndexOutOfRangeErrorMessage("Out of range").SetInvalidPageIndexErrorMessage("Invalid page index"));
            string htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr, " data-outrangeerrmsg=\"Out of range\" ");
            StringAssert.Contains(htmlStr, " data-invalidpageerrmsg=\"Invalid page index\"");
        }

        [TestMethod]
        public void CustomRoute_CurrentPageIndexIs1_ShouldGenerateCorrectFirstPageUrlAndUrlFormatAttributes()
        {
            _htmlHelper = TestHelper.GetHtmlHelper(
                                                  new RouteValueDictionary
                                                      {
                                                          {"controller", "Controls"},
                                                          {"action", "MvcPager"}
                                                      });
            var pagingRoute = _htmlHelper.RouteCollection.MapRoute("Paging", "{controller}/{action}/page_{id}",
                                                                   new {controller = "Home", action = "Index", id = 1});
            _htmlHelper.ViewContext.RouteData.Route = pagingRoute;
            _testList.CurrentPageIndex = 8;
            IHtmlString html =
                _htmlHelper.Pager(_testList).Options(o => o.SetPageIndexParameterName("id").SetRouteName("Paging"));
            string htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr," data-firstpage=\"" + AppPathModifier + "/Controls/MvcPager/page_1\"",
                          "Url of the first page is incorrect");
            StringAssert.Contains(htmlStr," data-urlformat=\"" + AppPathModifier + "/Controls/MvcPager/page___id__\"",
                "Paging url format is incorrect");
        }

        [TestMethod]
        public void DefaultRoute_DefaultPageIndexParameterNameWithExtrIdRouteData_ShouldGenerateCorrectLinks()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 4;
            IHtmlString html = _htmlHelper.Pager(_testList);
            string htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr, " data-firstpage=\"" + BaseLink + "/2\"",
                          "first page url is incorrect");
            StringAssert.Contains(htmlStr, "3",
                          "paging link is incorrect");
            StringAssert.Contains(htmlStr, " data-urlformat=\"" + BaseLink + "/2?pageindex=__pageindex__\"",
                "url format is incorrect");
        }

        [TestMethod]
        public void MultipleMvcPager_ShouldGenerateCorrectUrlForDataAttributesAndLinks()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 6;
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                       {
                                                           PageIndexParameterName = "id"
                                                       });
            var htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr, "4",
                          "Paging url of the first MvcPager is incorrect");
            StringAssert.Contains(htmlStr, " data-firstpage=\"" + BaseLink + "\"",
                          "Value of firstpage data attribute of the first MvcPager is incorrent");
            StringAssert.Contains(htmlStr, " data-urlformat=\"" + BaseLink + "/__id__",
                          "Value of urlformat data attribute of the first MvcPager is incorrect");

            var plist=new PagedList<int>(Enumerable.Range(1,33),3,5);
            html = _htmlHelper.Pager(plist, new PagerOptions { RouteName = "Default" });
            htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr, " data-firstpage=\"" + BaseLink + "/2\"",
                          "Value of firstpage data attribute of the second MvcPager is incorrent");
            StringAssert.Contains(htmlStr, " data-urlformat=\"" + BaseLink + "/2?pageindex=__pageindex__",
                "Value of urlformat data attribute of the second MvcPager is incorrect");
        }

        [TestMethod]
        public void RouteWithConstraintOnPageIndexParameter_ShouldGenerateCorrectUrlFormat()
        {
            _htmlHelper = TestHelper.GetHtmlHelper(new RouteValueDictionary(new{controller="articles",action="list"}));
            _testList.CurrentPageIndex = 6;
            IHtmlString html = _htmlHelper.Pager(_testList,
                new PagerOptions
                {
                    PageIndexParameterName = "id",
                    RouteName = "constraintroute"
                });
            var htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr, " data-urlformat=\"" + AppPathModifier + "/articles/list/__id__",
                "Value of urlformat data attribute is incorrect");
        }

        [TestMethod]
        public void DefaultrouteWithExtraRouteValues_ShouldGenerateCorrectUrlWithParameters()
        {
            _htmlHelper =
                TestHelper.GetHtmlHelper(new RouteValueDictionary { { "author", "Webdiyer" }, { "city", "Wuqi" }, { "id", 6 } });
            _testList.CurrentPageIndex = 6;
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id"
                                                   });
            var htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr, " data-firstpage=\"" + BaseLink + "?author=Webdiyer&city=Wuqi\"",
                "Value of firstpage data attribute of the first MvcPager is incorrent");
            StringAssert.Contains(htmlStr, " data-urlformat=\"" + BaseLink + "/__id__?author=Webdiyer&city=Wuqi\"","Value of urlformat data attribute is incorrent");
        }

        [TestMethod]
        public void MultipleMvcPagersWithExtraRouteValues_ShouldGenerateCorrectUrlWithParameters()
        {
            _htmlHelper =
                TestHelper.GetHtmlHelper(new RouteValueDictionary { { "author", "Webdiyer" }, { "city", "Wuqi" }, { "id", 6 } });
            _htmlHelper.Pager(_testList, new PagerOptions
            {
                PageIndexParameterName = "id"
            });
            _testList.CurrentPageIndex = 5;
            IHtmlString html = _htmlHelper.Pager(_testList);
            var htmlStr = html.ToHtmlString();
            StringAssert.Contains(htmlStr, " data-firstpage=\"" + BaseLink + "/6?author=Webdiyer&city=Wuqi\"",
                "Value of firstpage data attribute of the second MvcPager is incorrent");
            StringAssert.Contains(htmlStr, " data-urlformat=\"" + BaseLink + "/6?author=Webdiyer&city=Wuqi&pageindex=__pageindex__",
                "Value of urlformat data attribute of the second MvcPager is incorrect");
        }

        [TestMethod]
        public void CurrentUICultureIsEnUs_ShouldGetCorrectPropertyValuesFromResourceFile()
        {
            _testList.PageSize = 5;
            _testList.CurrentPageIndex = 13;
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id"
                                                   });
            const string linkFormat = "{1}";
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-currentpage=\"13\"", "data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"18\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First");
            sb.AppendFormat(linkFormat, 12, "Prev");
            sb.AppendFormat(linkFormat, 7, "...");
            for (int i = 8; i < 18; i++)
            {
                if (i == 13)
                    sb.Append(i);
                else
                    sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 18, "...");
            sb.AppendFormat(linkFormat, 14, "Next");
            sb.AppendFormat(linkFormat, 18, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void CurrentUICultureIsZhCN_ShouldGetCorrectPropertyValuesFromResourceFile()
        {
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("zh-CN");
            _testList.PageSize = 5;
            _testList.CurrentPageIndex = 13;
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id"
                                                   });
            const string linkFormat = "{1}";
            var sb = new StringBuilder(TestHelper.CopyrightTextCn);
            var attrs = new[]
            {
                "data-currentpage=\"13\"", "data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessageCn + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessageCn + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"18\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("首页");
            sb.AppendFormat(linkFormat, 12, "上页");
            sb.AppendFormat(linkFormat, 7, "...");
            for (int i = 8; i < 18; i++)
            {
                if (i == 13)
                    sb.Append(i);
                else
                    sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 18, "...");
            sb.AppendFormat(linkFormat, 14, "下页");
            sb.AppendFormat(linkFormat, 18, "尾页");
            sb.Append("
").Append(TestHelper.CopyrightTextCn);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void AlwaysShowFirstLastPageNumberWithPageIndexIs7_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.PageSize = 5;
            _testList.CurrentPageIndex = 7;
            var po = new PagerOptions
            {
                PageIndexParameterName = "id",
                AlwaysShowFirstLastPageNumber = true,
                ShowFirstLast = false,
                ShowPrevNext = false
            };

            IHtmlString html = _htmlHelper.Pager(_testList, po);
            const string linkFormat = "{1}";
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-currentpage=\"7\"", "data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"18\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("1");
            for (int i = 2; i <= 11; i++)
            {
                if (i == 7)
                    sb.Append(i);
                else
                    sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 12, "...");
            sb.AppendFormat(linkFormat, 18, 18);
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void AlwaysShowFirstLastPageNumber_PageIndexIs13AndPageSizeIs5_ShouldGenerateCorrectHtml()
        {
            _testList.PageSize = 5;
            _testList.CurrentPageIndex = 13;
            var po = new PagerOptions
            {
                PageIndexParameterName = "id",
                AlwaysShowFirstLastPageNumber = true,
                ShowFirstLast = false,
                ShowPrevNext = false
            };

            _htmlHelper = TestHelper.GetHtmlHelper();

            IHtmlString html = _htmlHelper.Pager(_testList, po);
            const string linkFormat = "{1}";
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-currentpage=\"13\"", "data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"18\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("1");
            sb.Append("...");
            for (int i = 8; i <= 18; i++)
            {
                if (i == 13)
                    sb.Append(i);
                else
                    sb.AppendFormat(linkFormat, i, i);
            }
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void SetAlwaysShowFirstLastPageNumber_PageIndexIs13AndPageSizeIs5_ShouldGenerateCorrectHtml()
        {
            _testList.PageSize = 5;
            _testList.CurrentPageIndex = 13;

            _htmlHelper = TestHelper.GetHtmlHelper();

            IHtmlString html = _htmlHelper.Pager(_testList).Options(o => o.SetPageIndexParameterName("id").AlwaysShowFirstLastPageNumber().HideFirstLast().HidePrevNext());
            const string linkFormat = "{1}";
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-currentpage=\"13\"","data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"18\"",
                "data-urlformat=\""+BaseLink+"/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("1");
            sb.Append("...");
            for (int i = 8; i <= 18; i++)
            {
                if (i == 13)
                    sb.Append(i);
                else
                    sb.AppendFormat(linkFormat, i, i);
            }
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void HtmlPagerWithAllParameters_ShouldGenerateCorrectHtml()
        {
            const string rootLink = AppPathModifier + "/MyController/MyAction";
            const string linkFormat = "{1}";
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(88, 10, 1,
                                                   new PagerOptions
                                                       {
                                                           ActionName = "MyAction",
                                                           ControllerName="MyController",
                                                           PageIndexParameterName = "id",
                                                           FirstPageText = "First Page",
                                                           PrevPageText = "Prev Page",
                                                           NextPageText = "Next Page",
                                                           LastPageText = "Last Page",RouteValues = new RouteValueDictionary { { "Controller", "MyController" }, { "Action", "MyAction" }, { "city", "Wuqi" }, { "nick", "Webdiyer" } },
                                                           HtmlAttributes = new Dictionary<string, object>{{"id","mypager"}}
                                                       });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"9\"",
                "data-urlformat=\""+rootLink+"/__id__?city=Wuqi&nick=Webdiyer\"","id=\"mypager\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First PagePrev Page1");
            for (int i = 2; i <= 9; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, "2", "Next Page");
            sb.AppendFormat(linkFormat, "9", "Last Page");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void SetAllParameters_ShouldGenerateCorrectHtml()
        {
            const string rootLink = AppPathModifier + "/MyController/MyAction";
            const string linkFormat = "{1}";
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(88, 10, 1).Options(o=>o.SetActionName("MyAction").SetControllerName("MyController").
                                                       SetPageIndexParameterName("id").
                                                       SetFirstPageText("First Page").SetPrevPageText("Prev Page").
                                                       SetNextPageText("Next Page").SetLastPageText("Last Page").
                                                       SetRouteValues(new RouteValueDictionary { { "Controller", "MyController" }, { "Action", "MyAction" }, { "city", "Wuqi" }, { "nick", "Webdiyer" } }).
                                                       SetHtmlAttributes(new Dictionary<string, object> { { "id", "mypager" } }));
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"9\"",
                "data-urlformat=\""+rootLink+"/__id__?city=Wuqi&nick=Webdiyer\"","id=\"mypager\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First PagePrev Page1");
            for (int i = 2; i <= 9; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, "2", "Next Page");
            sb.AppendFormat(linkFormat, "9", "Last Page");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void CustomHtmlAttributesValue_ShouldGenerateCorrectHtmlAttributes()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id", HtmlAttributes = new Dictionary<string, object> { { "aaa", "98%" }, { "bbb", "26px" }, { "ccc", "both" } } });
            var attrs = new[]
            {
                "aaa=\"98%\"", "bbb=\"26px\"","ccc=\"both\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            var sb=new StringBuilder("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            StringAssert.Contains(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void HtmlAttributesWithStyleValue_ShouldGenerateCorrectStyleAttribute()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id",HorizontalAlign = "right",HidePagerItems = true,  HtmlAttributes = new Dictionary<string, object> { { "style", "width:95%;height:28px" }}});
            StringAssert.Contains(html.ToHtmlString(), " style=\"width:95%;height:28px;text-align:right;display:none\"");
        }

        [TestMethod]
        public void SetHtmlAttributesWithStyleValue_ShouldGenerateCorrectStyleAttribute()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetPageIndexParameterName("id").SetHorizontalAlign("right").HidePagerItems().SetHtmlAttributes(new Dictionary<string, object> { { "style", "width:95%;height:28px" } } ));
            StringAssert.Contains(html.ToHtmlString(), " style=\"width:95%;height:28px;text-align:right;display:none\"");
        }

        [TestMethod]
        public void HidePagerItemsAndCurrentPageIndexIs1_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id", HidePagerItems = true });
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\"","style=\"display:none\""
            };
            var sb=new StringBuilder("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">
");
            Assert.AreEqual(html.ToHtmlString(), TestHelper.CopyrightText + sb + TestHelper.CopyrightText);
        }

        [TestMethod]
        public void HidePagerItemsAndCurrentPageIndexIs6_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 6;
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id", HidePagerItems = true });
            var attrs = new[]
            {
                "data-currentpage=\"6\"","data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\"","style=\"display:none\""
            };
            var sb = new StringBuilder("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">
");
            Assert.AreEqual(html.ToHtmlString(), TestHelper.CopyrightText + sb + TestHelper.CopyrightText);
        }

        [TestMethod]
        public void CurrentPagerItemTemplate_ShouldGenerateCorrentHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 2;
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                       {
                                                           PageIndexParameterName = "id",
                                                           CurrentPagerItemTemplate =
                                                               "{0}"
                                                       });
            StringAssert.Contains(html.ToHtmlString(),"2");
        }

        [TestMethod]
        public void AddPagerItemHtmlAttributes_ShouldGenerateCorrectAttribute()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList)
                .Options(o =>
                    o.SetPagerItemTemplate("{0}")
                        .AddPagerItemHtmlAttributes("class", "paginator")
                        .AddPagerItemHtmlAttributes("style", "margin-right:5px;"));
            StringAssert.Contains(html.ToHtmlString(), " class=\"paginator\"");
            StringAssert.Contains(html.ToHtmlString(), " style=\"margin-right:5px;\"");
        }

        [TestMethod]
        public void CurrentPageNumberFormatStringAndPagerItemTemplate_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "{1}";
            _testList.CurrentPageIndex = 6;
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                       {
                                                           PageIndexParameterName = "id",
                                                           CurrentPagerItemTemplate =
                                                               "{0}",
                                                           CurrentPageNumberFormatString = "-{0}-"
                                                       });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-currentpage=\"6\"", "data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.AppendFormat("First", BaseLink);
            sb.AppendFormat(linkFormat,5,"Prev");
            sb.AppendFormat("1",BaseLink);
            for (int i = 2; i <= 10; i++)
            {
                if (i == 6)
                    sb.Append("-6-");
                else
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 7, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void SetCurrentPageNumberFormatStringAndPagerItemTemplate_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "{1}";
            _testList.CurrentPageIndex = 6;
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetPageIndexParameterName("id").SetCurrentPagerItemTemplate("{0}").SetCurrentPageNumberFormatString("-{0}-"));
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-currentpage=\"6\"","data-firstpage=\"" + BaseLink + "\"",
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.AppendFormat("First", BaseLink);
            sb.AppendFormat(linkFormat, 5, "Prev");
            sb.AppendFormat("1", BaseLink);
            for (int i = 2; i <= 10; i++)
            {
                if (i == 6)
                    sb.Append("-6-");
                else
                    sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 7, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void PageNumberFormatString_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "[{1}]";
            const string txtLinkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id",
                                                       PageNumberFormatString = "[{0}]"
                                                   });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First")
                .Append("Prev")
                .Append("[1]");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(txtLinkFormat, 11, "...");
            sb.AppendFormat(txtLinkFormat, 2, "Next");
            sb.AppendFormat(txtLinkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void ContainerTagNameAndPagerItemTemplate_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "
{1}
";
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       ContainerTagName = "ul",
                                                       PageIndexParameterName = "id",
                                                       PagerItemTemplate = "
{0}
"});
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("
First
")
                .Append("
Prev
")
                .Append("
1
");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(),sb.ToString());
        }

        [TestMethod]
        public void SetContainerTagNameAndPagerItemTemplate_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "
{1}
";
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetContainerTagName("ul").SetPageIndexParameterName("id")
                                                       .SetPagerItemTemplate("
{0}
"));
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("
First
")
                .Append("
Prev
")
                .Append("
1
");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void DisabledPagerItemTemplate_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id",
                                                       DisabledPagerItemTemplate = "{0}"
                                                   });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First")
                .Append("Prev")
                .Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void DisabledPagerItemTemplate_ShouldOverridePagerItemTemplate()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "
{1}
";
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       ContainerTagName = "ul",
                                                       PageIndexParameterName = "id",
                                                       DisabledPagerItemTemplate = "
{0}
",
                                                       CurrentPagerItemTemplate = "
{0}
",
                                                       PagerItemTemplate = "
{0}
"
                                                   });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("
First
")
                .Append("
Prev
")
                .Append("
1
");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void SetDisabledPagerItemTemplate_ShouldOverridePagerItemTemplate()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "
{1}
";
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetContainerTagName("ul").SetPageIndexParameterName("id").
                                                       SetDisabledPagerItemTemplate("
{0}
").
                                                       SetCurrentPagerItemTemplate("
{0}
").
                                                       SetPagerItemTemplate("
{0}
"));
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("
First
")
                .Append("
Prev
")
                .Append("
1
");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void CurrentPagerItemTemplate_ShouldInheritFromNumericPagerItemTemplate()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 2;
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id",
                                                       NumericPagerItemTemplate ="{0}"
                                                   });
            StringAssert.Contains(html.ToHtmlString(), "2");
        }

        [TestMethod]
        public void DisabledPagerItemTemplate_ShouldInheritFromNavigationPagerItemTemplate()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       PageIndexParameterName = "id",
                                                       NavigationPagerItemTemplate = "{0}"
                                                   });
            StringAssert.Contains(html.ToHtmlString(), "First");
        }

        [TestMethod]
        public void NumericPagerItemTemplate_ShouldOverridePagerItemTemplate()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "{1}";
            const string numericLinkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList,
                                                   new PagerOptions
                                                   {
                                                       ContainerTagName = "ul",
                                                       PageIndexParameterName = "id",
                                                       PagerItemTemplate = "{0}",
                                                       NumericPagerItemTemplate = "{0}"
                                                   });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\""+BaseLink+"/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First")
                .Append("Prev")
                .Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(numericLinkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void SetNumericPagerItemTemplate_ShouldOverridePagerItemTemplate()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            const string linkFormat = "{1}";
            const string numericLinkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetContainerTagName("ul").SetPageIndexParameterName("id").SetPagerItemTemplate("{0}")
                                                       .SetNumericPagerItemTemplate("{0}"));
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First")
                .Append("Prev")
                .Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(numericLinkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void DefaultRoute_NullPagerOptions_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 1;
            const string linkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList,null);
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"pageindex\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\""+BaseLink+"/2?pageindex=__pageindex__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First").Append("Prev").Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void CurrentPageIndexIsLargerThanTotalPageCount_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 88;
            IHtmlString html = _htmlHelper.Pager(_testList, null);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"", "data-pagerid=\"Webdiyer.MvcPager\"",
                "style=\"color:red;font-weight:bold\""
            };
            var sb=new StringBuilder("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">").Append(TestHelper.PageIndexOutOfRangeErrorMessage).Append("
");
            Assert.AreEqual(html.ToHtmlString(), TestHelper.CopyrightText + sb + TestHelper.CopyrightText);
        }

        [TestMethod]
        public void NavigationPagerItemsPositionIsLeft_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 1;
            const string linkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id", NavigationPagerItemsPosition = PagerItemsPosition.Left });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\""+BaseLink+"/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First").Append("Prev");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last").Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void NavigationPagerItemsPositionIsRight_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 1;
            const string linkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id", NavigationPagerItemsPosition = PagerItemsPosition.Right });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\""+BaseLink+"/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            //sb.Append("
");
            sb.Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...").Append("First").Append("Prev");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void SetNavigationPagerItemsPositionToRight_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 1;
            const string linkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetPageIndexParameterName("id").SetNavigationPagerItemsPosition(PagerItemsPosition.Right));
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...").Append("First").Append("Prev");
            sb.AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void OnPageIndexError_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 1;
            const string linkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList, new PagerOptions { PageIndexParameterName = "id", OnPageIndexError="alert('page index error:'+err)" });
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\""+BaseLink+"/__id__\"","data-onerror=\""+HttpUtility.HtmlEncode("alert('page index error:'+err)")+"\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First").Append("Prev").Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...").AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }

        [TestMethod]
        public void SetOnPageIndexError_ShouldGenerateCorrectHtml()
        {
            _htmlHelper = TestHelper.GetHtmlHelper();
            _testList.CurrentPageIndex = 1;
            const string linkFormat = "{1}";
            IHtmlString html = _htmlHelper.Pager(_testList).Options(o=>o.SetPageIndexParameterName("id").SetOnPageIndexError("alert('page index error:'+err)"));
            var sb = new StringBuilder(TestHelper.CopyrightText);
            var attrs = new[]
            {
                "data-invalidpageerrmsg=\"" + TestHelper.InvalidPageIndexErrorMessage + "\"",
                "data-outrangeerrmsg=\"" + TestHelper.PageIndexOutOfRangeErrorMessage + "\"",
                "data-pageparameter=\"id\"", "data-pagerid=\"Webdiyer.MvcPager\"", "data-pagecount=\"11\"",
                "data-urlformat=\"" + BaseLink + "/__id__\"","data-onerror=\"" + HttpUtility.HtmlEncode("alert('page index error:'+err)") + "\""
            };
            sb.Append("
 a))
            {
                sb.Append(" ").Append(att);
            }
            sb.Append(">");
            sb.Append("First").Append("Prev").Append("1");
            for (int i = 2; i <= 10; i++)
            {
                sb.AppendFormat(linkFormat, i, i);
            }
            sb.AppendFormat(linkFormat, 11, "...").AppendFormat(linkFormat, 2, "Next");
            sb.AppendFormat(linkFormat, 11, "Last");
            sb.Append("
").Append(TestHelper.CopyrightText);
            Assert.AreEqual(html.ToHtmlString(), sb.ToString());
        }
    }
}


"Ruzgarin Hatiralari" ("Memories of the Wind)", directed by Ozcan Alper, is a film marred by tragedy that draws the portrait of a pained society. The year is 1943 and Turkey is caught between two worlds — that of Adolf Hitler's Nazi Europe and Stalin's impregnable U.S.S.R. The Turkish government perceives communism as a threat to its national security, but it is not under immediate control of the Nazis and battles with its political ideology.
The main character is an artist and poet named Aram who is forced to flee Istanbul because of his left-leaning political views. He finds refuge in the mountains of the Turkish-Georgian border, in the home of Mikahil, an informant for the Russians, and his younger Russian wife, Meryem.
The majority of the film's 122 minutes is spent in these mountains that seem to trap the main character as much as they protect him. Aram is not a very talkative poet, Mikahil is stoic and Meryem's voice is first heard only half-way through the story — such that words in this film are as scarce as they are precious. A quiet love story builds between Aram and Meryem, drawn in tacit moments and hidden longing.
None of the characters are ever fully able to express and develop their feelings and thoughts. Each finds themselves turning to another, saying their name and then — "Nothing." The simple phrase seems to imply the character wants to express complex emotions but is unable to find the right words in that particular moment. Each unspoken word amounts to a seemingly insurmountable disconnect between characters that is truly one of the most tragic aspects of the storyline. The characters are trapped in their solitude, unable to form the human connection that they long for.
Aram's stay in the Turkish rural countryside as he waits to be smuggled into Russia mirrors his childhood trauma. He is a man tortured by his past and his present, as the narrative reveals that Aram is a survivor of the Armenian genocide of 1915. Through a series of flashbacks, he is slowly able to weave together the scattered pieces of his bloody childhood. He uses sketching in his notebook as a medium for coping with his trauma, remembering how he and his family fled from the Turkish military. His survival of that ordeal invigorates his life through the troubling times in which the movie is set. Alper's choice to tackle both the universally troubling times in the Second World War and the highly contested events of 1915 is incredibly bold.
"Memories of the Wind" is an ambitious film that strives to depict and denounce Turkey's checkered past during the two world wars. Aram, a fictional character created by Alper, is a man twice targeted by his society — once as an Armenian child and later as a political black sheep. The story is told in long shots and sober lighting that no doubt reflect the dreary if not anxious times the story is set in. Violence is implied in the last quarter of the movie, but it is never gruesome as it is never fully shown. While the story progression is slow, Alper spins a veritable intrigue that ensures a viewer's continued attention.


A fabulous plus size knit top it sports a soft, see-through fabric, dolman short sleeves, rounded neckline and ruching at sides. Great for plus size clubwear or any occasion! Get that model look! Limited in stock, get this while you can!


Some 80 sixth form students with an interest in science and engineering attended from schools and colleges in Kent and South East London.
This year, the schools attending the two-day workshop were: Tonbridge School, Dane Court Grammar, Chatham Grammar, Newstead Wood School, Cleeve Park, Dartford Grammar, Holmesdale Technology College, Wilmington Grammar, Beths, Wimbledon High, Fortismere, St Marylebone, Simon Langton Boys and Kent College.
Participating companies include: Pfizer, BAE Systems, Instro Precision, DSTL, Balfour Beatty, Crofton Design, SEM, Pavegen, Atkins, Laing O'Rourke, IPS International, Ramboll and Arup.
The projects ranged from designing a new Helicopter flight stick to developing a low noise technique for breaking rocks.


This Agreement (the "Agreement") governs the use of any and all OfficeRnD™ Services by the company or organization named in the Order Form (or other form of registration) completed or submitted by you (as defined below, "Subscriber"). By executing and returning to OfficeRnD an Order Form, or by clicking the button during the registration process ("OK, I confirm that I have read and accepted the Terms") or otherwise using the Services, you expressly agree on behalf of Subscriber to be bound by and comply with this Agreement. If you are not authorised to enter into this Agreement on behalf of Subscriber or Subscriber does not agree to be bound by any term or condition contained in this Agreement, do not use the Services. This Agreement is effective as between Subscriber and OfficeRnD from the earliest date on which you returned to OfficeRnD an executed Order Form, clicked the confirm button during the registration process or otherwise started to use the Services.
"API" means the OfficeRnD Application Program Interface and associated documentation.
"Account Holder" means the individual(s) appointed by Subscriber to manage the Account and Users on behalf of the Subscriber. All Account Holders must be employees of Subscriber.
"Asset" means a real estate resource with economic value registered at a geographical address that an individual, corporation or country owns or controls with the expectation that it will provide future benefit.
"Content" means all documents, files, contact details, discussions, tasks, meetings, electronic media, calendar dates, visual, written or audible data, information or material associated to the management of Assets, that is entered into, uploaded to, posted, transmitted or displayed through the Services by Subscriber or any User, including, without limitation, any hyperlink, graphic, artwork, video, music, text, image, logo, document, spreadsheet, presentation, text message, form entry, web page or other data.
"Intellectual Property Rights" means all right, title, and interest in and to any copyright, database, design, logo, trademark, service mark, patent, invention, trade secret, domain name, confidential and proprietary information, know-how, technology, business name, trade name, trade dress, technical solutions, associated right to sue (past, present, and future), and any other intellectual property rights whether existing at common law, applied for, registered or unregistered and all extensions, renewals, continuations, continuations in part, divisionals, reissues, re-examinations, and revivals thereof and existing anywhere in the world.
"Order Form" means any written or electronic document or registration form for placing orders for the Services and any addenda or amendments thereof, entered into contemporaneously with this Agreement or from time to time thereafter. Each Order Form shall be governed by and deemed to incorporate the terms and conditions contained herein, except as otherwise expressly provided in the Order Form. Each Order Form will describe all of the Services that OfficeRnD agree to make available to Subscriber.
"Package" means the level of the Services Subscriber has been licensed to use, as provided on the Order Form, which details the features and limits to the features Subscriber is permitted to use.
"Services" means, collectively, the computer applications, interfaces, software, programs, products, services and websites provided or made available by OfficeRnD and its affiliates pursuant to any Order Form, including provision of access to the Website for, among other things, creating and managing the Account.
"Subscriber" means the company, organization, employer, principal or other legal entity named in each Order Form and for whom OfficeRnD provide the Services pursuant to this Agreement.
"User" means an individual who has completed the user registration process and created a user account at the Website. This includes any individual that OfficeRnD create a user account for at Subscriber's direction and any individual invited by Subscriber to become a user.
"Website" means the website at http://code.slicecrowd.com/OfficeRnD-backup; https://app.officernd.com and any other URLs maintained by OfficeRnD for the purpose of making the Services accessible to Users.
"We/Us/Our/OfficeRnD" means the OfficeRnD company described in Section 14 'Governing Law; Jurisdiction'.
"Account" means an interface within the Website configured for Users authorised by Subscriber to upload, manage and share files and information including Content.
In this Agreement, unless the context requires otherwise, any phrase introduced by the words "including", "include", "in particular", "for example" or any similar expression shall be construed as illustrative only and shall not be construed as limiting the generality of any preceding words, and references to the singular include the plural and in each case vice versa.
The headings and sub headings in this Agreement are inserted for convenience only and shall not affect the meaning of this Agreement.
Subject to the terms of this Agreement, OfficeRnD hereby grant to Subscriber a non-transferable, non-exclusive, non-sublicensable limited term right and licence to access and use, and to authorise and permit Users to access and use, the Services, solely as provided in each Order Form. Except for the rights specifically granted under this Agreement, Subscriber is not given any right, title or interest in or to the Services or Website, and OfficeRnD expressly reserve all such rights, title and interests.
All Content shall remain Subscriber's sole property or the property of its respective legal owner. OfficeRnD shall have no liability for such Content. By uploading Content, Subscriber represents and warrants that it has obtained all necessary licences, permissions, consents and agreements necessary for the lawful use of such Content by OfficeRnD and by third parties in accordance with this Agreement and in order for OfficeRnD to provide the Services. Subscriber acknowledges and agrees OfficeRnD does not control the Content posted by Users, and does not guarantee the accuracy, integrity or quality of such Content. Subscriber agrees that Subscriber must evaluate, and bear all risks associated with, the use of any third party Content, including any reliance on the accuracy, completeness, or usefulness of such Content. Under no circumstances will OfficeRnD be liable in any way for any third party Content, including, but not limited to, any errors or omissions in any third party content, or any loss or damage of any kind incurred as a result of the use of any third party Content posted, emailed, transmitted or otherwise made available via the Services or Website.
Subscriber agrees to use the Services within the parameters of the Package Subscriber has purchased. OfficeRnD reserves the right to terminate the Services immediately on breach of this clause and OfficeRnD are under no obligation to provide a refund in full or in part for the fees paid.
The Services are normally available over the Internet around the clock. OfficeRnD shall be entitled to take measures that affect the aforementioned accessibility when OfficeRnD deem such to be necessary for technical, maintenance, operational, or security reasons. OfficeRnD guarantee at least 99.5% total uptime of the Service, as measured over a rolling 3 month (90 day) period by a reputable external monitoring service of our choice from time to time. This excludes any planned maintenance periods as described below. Availability is currently measured as continuous availability of the OfficeRnD login page, tested every minute from one of at least 8 global locations. OfficeRnD will make available the official uptime reports to Subscriber on request. OfficeRnD will notify Subscriber at least 2 weeks in advance of any planned maintenance periods that exceed 15 minutes in length. OfficeRnD will endeavour to carry out any such planned maintenance outside of normal UK office hours. There will be a maximum of one (1) planned maintenance period in any three (3) week period. OfficeRnD will backup Subscriber's data stored on Our system, including files stored in the Subscriber Account and associated User data such as notifications, permissions and comments. Backups of the OfficeRnD file store are carried out daily at our disaster recovery data centre. Full backups of the OfficeRnD database are carried out on a regular basis. At a minimum, OfficeRnD takes full snapshots every 24 hours, ensuring that in the event of a serious issue, the oldest your data will be is 24 hours. Any problems experienced by Subscriber in accessing the Service should be reported to OfficeRnD through the Website or at support@code.slicecrowd.com The service levels as described above are compensated by OfficeRnD as follows: If OfficeRnD fail to meet the described service levels for service availability, OfficeRnD will compensate Subscriber by crediting Subscriber one day of Subscriber annual fee for each one hour of downtime. If availability of the Service as described in this clause is lower than 75% (seventy five percent) in any 3 month (90 day) period Subscriber shall be able to terminate Subscriber Agreement with immediate effect.
OfficeRnD assume no responsibility for technical support or problems arising from or relating to third party systems, equipment owned or maintained by Subscriber or any Users, or the administration of email addresses or the email account of any User.
OfficeRnD agree to take commercially reasonable steps to maintain the Services in a secure manner. If a security flaw is detected with respect to which OfficeRnD has reason to believe the security or integrity of Content or account information of Subscriber's Users may be affected, OfficeRnD shall use reasonable efforts to notify Subscriber promptly of such defect and any related remedial steps OfficeRnD propose to take.
OfficeRnD reserve the right at any time and from time to time to reasonably modify or discontinue, temporarily or permanently, the Services or Website (or any part thereof), including but not limited to modifications to the design, operational method, technical specifications, systems, and other functions. However any changes will not materially limit the scope of the Services. Subscriber agrees that OfficeRnD shall not be liable to Subscriber or to any third party for any modification, suspension, or discontinuance of the Services or Website (except for refunding to Subscriber any prepaid fees corresponding to the period following any permanent discontinuance of Services other than due to Subscriber's breach).
Services may be performed by Our affiliates or subcontractors in Our discretion, provided that OfficeRnD shall be responsible for compliance with and performance of this Agreement by any such persons and such persons will be under the same confidentiality provisions as set forth in this Agreement.
The Services or Website may contain links to third party websites that are not owned or controlled by OfficeRnD. These links are provided solely for Users' convenience. OfficeRnD have no control over any linked third party sites, are not responsible for the content of such sites, and make no representations or warranties with respect to such sites.
consent and authorise OfficeRnD to verify any Registration Data. If Subscriber or a User provides any information that is untrue, inaccurate, not current or incomplete, or OfficeRnD have a reasonable belief that such information is untrue, inaccurate, not current, or incomplete, OfficeRnD have the right to suspend or terminate the relevant User accounts and refuse any current or future use of the Services or Website.
protect the rights, property, or personal safety of OfficeRnD, other Users, or the public.
Where OfficeRnD is required to access and disclose Subcriber's account information and Content, OfficeRnD will use commercially reasonable efforts, to the extent OfficeRnD are permitted to do so, to give Subscriber as much notice of this disclosure as possible.
Subscriber agrees to notify OfficeRnD immediately of any unauthorised use of Subscriber's account, the login credentials of any of Subscriber's Users, or any other breach of security. Subscriber may be held liable for losses incurred by OfficeRnD or any User of the Services or Website due to someone else using the Registration Data.
Subscriber represents that Subscriber is authorised to receive the Services under the laws of the geographical jurisdictions in which Subscriber and Subscriber's Users are located. Subscriber shall be responsible for all activities, communications and transactions of Subscriber and Subscriber's employees and agents conducted through use of the Services and Website and their compliance with applicable national, federal, state and local laws.
Subscriber agrees that OfficeRnD may include Subscriber's company name and/or logo among our clients listed in Our marketing materials, including the Website. Nothing herein shall require Subscriber to endorse the Services.
Both parties agree that a breach of this Agreement by either party may cause the other party substantial and irreparable damages and, therefore, in the event of any such breach, in addition to other remedies which may be available, the other party shall have the right to seek specific performance and other injunctive and equitable relief.
Subscriber agrees that Subscriber is solely responsible for (and that OfficeRnD have no responsibility to Subscriber or to any third party for) any services and/or products Subscriber provide or use through any 3rd party software.
Subscriber expressly understand and agree that OfficeRnD shall not be liable for any direct, indirect, incidental, special, consequential or exemplary damages, including but not limited to, damages for loss of profits, goodwill, use, data or other intangible losses (even if OfficeRnD has been advised of the possibility of such damages), resulting from Subscriber use of the API or third-party products that access data via the API.
Subscriber will not collect any users' personal information or data in a misleading, illegal, unauthorised or unfair way. Without limiting the generality of the foregoing, Subscriber will never collect, store or record passwords used by users' to log-in to the Services. If users need a separate password to use Subscriber software Subscriber will generate a unique password and securely communicate it to the user. Subscriber agrees that any 3rd party software shall be provided by Subscriber in compliance with all applicable laws and regulations (including without limitation those relating to the protection of privacy and the processing of personal data or traffic data).
Subscriber will not use the API to create software that sends unsolicited communications (whether commercial or otherwise) to any third party.
OfficeRnD reserve the right at any time to modify or discontinue, temporarily or permanently the API (or any part thereof). Where OfficeRnD permanently discontinues the API, OfficeRnD will continue to provide appropriate levels of support to ensure continuance of the API which has just been replaced for a period not less than 6 months to be determined by OfficeRnD, in our sole discretion.
Abuse or excessively frequent requests to the Services via the API may result in the temporary or permanent suspension of Subscriber account's access to the API. OfficeRnD, in our sole discretion, will determine abuse or excessive usage of the API.
OfficeRnD retain the right to the Services, including the API. In no way will Subscriber pass off, market or otherwise make representations that the OfficeRnD brand, Services or Website is owned or otherwise connected with Subscriber. Subscriber must make it clear that Subscriber are allowing access to the OfficeRnD API via an independent 3rd party piece of software and must prominently display the following text: "This product uses the OfficeRnD API but is not endorsed, certified or otherwise approved in any way by OfficeRnD". Subscriber shall not have any rights to use OfficeRnD trademarks or logos.
OfficeRnD reserves the right to limit Subscriber access to the API or the number of calls Subscriber software can otherwise make to it, except solely as agreed in a separate written order.
OfficeRnD reserve the right to make information about any software or website that uses the API available to our users on our Website and any other marketing collateral.
Each receiving party agrees that it shall use Confidential Information of the disclosing party solely in furtherance of the performance of this Agreement and for no other purpose. Each party shall use the same degree of care to protect the other party's Confidential Information as it uses to protect its own confidential information of like nature, but in no circumstances with less than reasonable care. Each party agrees not to disclose the other party's Confidential Information to any person or entity other than: (i) to employees, agents, subcontractors or consultants of the receiving party on an as-needed basis, provided such persons have entered into written confidentiality agreements consistent with this Section 7 or otherwise are bound under substantially similar confidentiality restrictions; (ii) with respect to Subscriber Confidential Information, as authorised by Subscriber; (iii) to the extent required by court order, legal process, governmental or exchange regulation or applicable law, provided that the party required to disclose the information provides prompt advance written notice thereof (to the extent permitted by law) to the other party; or (iv) otherwise solely as expressly authorised in writing by the disclosing party. Notwithstanding any provision hereof to the contrary, OfficeRnD may use and disclose anonymous, aggregated data and statistics regarding use of the Services, provided no individual organization or person can be identified and no Content is disclosed in connection with such data and statistics.
Each party acknowledges and agrees the use or disclosure of Confidential Information inconsistent with this Agreement could cause irreparable harm to a disclosing party, the extent of which would be difficult to ascertain. Accordingly, each party agrees that, in addition to any remedies available at law, any non-breaching party shall have the right to obtain immediate injunctive relief, without the necessity of posting a bond, in the event of a breach or threatened breach of this Section 7 by the other party, any of its affiliates or their representatives. This Section 7 shall survive termination or expiration of this Agreement.
OfficeRnD warrants, to the best of its knowledge after implementing reasonable measures, that components of the Services and Website made accessible to Subscriber do not contain viruses, worms, code or other third party computer code intentionally designed to disrupt, disable, or harm the operation of Subscriber's computer systems. OfficeRnD further warrant, to the best of Our knowledge, that the Services do not infringe any third party trade secret, copyright, issued patent or trademark. OTHER THAN THE FOREGOING, THE SERVICES AND WEBSITE ARE PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS WITHOUT WARRANTY OF ANY KIND. OFFICERND MAKE NO WARRANTY THE SERVICES WILL BE ERROR FREE OR AVAILABLE AT ALL TIMES, NOR DOES OFFICERND WARRANT THE COMPATIBILITY OR OPERATION OF THE SERVICES WITH ALL SUBSCRIBER OR USER SITES, HARDWARE OR SOFTWARE CONFIGURATIONS. EXCEPT AS SET FORTH IN THIS SECTION 8, OFFICERND MAKES AND SUBSCRIBER RECEIVES NO WARRANTIES, EXPRESS OR IMPLIED, REGARDING OR RELATING TO THE SUBJECT MATTER HEREOF. OFFICERND DISCLAIMS, TO THE FULLEST EXTENT PERMITTED BY LAW, ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT WITH RESPECT TO THE SUBJECT MATTER HEREOF. SUBSCRIBER HEREBY ACKNOWLEDGES THAT IT HAS NOT RELIED ON ANY WARRANTY, CONDITION, GUARANTY OR REPRESENTATION BY OFFICERND OR ITS REPRESENTATIVES OTHER THAN THOSE CONTAINED IN THIS AGREEMENT.
to repair, upgrade, or otherwise enhance the performance of OfficeRnD to address the failure of performance.
Indemnification under subsections 9.1 and 9.2 hereof will be provided only on the conditions that: (i) the indemnifying party is given written notice promptly after the indemnified party receives notice of the subject Action; provided, however, that late notice shall only excuse the indemnifying party from its obligations hereunder if such late notice materially prejudices the indemnifying party; (ii) the indemnifying party has sole control of the defense and all related settlement negotiations, provided any settlement that would impose any monetary or injunctive obligation upon the indemnified party shall be subject to such party's prior written approval; and (iii) the indemnified party provides cooperation and information in furtherance of such defense, as reasonably required by the indemnifying party. This Section 9 shall survive termination or expiration of this Agreement.
EXCEPT FOR CLAIMS FOR PERSONAL INJURY (INCLUDING DEATH) AND CLAIMS BASED ON WILLFUL MISCONDUCT OR FRAUD, NEITHER PARTY SHALL BE LIABLE TO THE OTHER FOR ANY INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, CONSEQUENTIAL OR EXEMPLARY DAMAGES ARISING FROM OR RELATED TO THE SERVICES OR THIS AGREEMENT, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, LOSS OF DATA OR BUSINESS OR OTHER INTANGIBLE LOSSES (EVEN IF A PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES).
EXCEPT FOR CLAIMS FOR PERSONAL INJURY (INCLUDING DEATH), CLAIMS BASED ON WILLFUL MISCONDUCT OR FRAUD, AND CLAIMS FOR INDEMNIFICATION UNDER SECTION 9, THE AGGREGATE LIABILITY OF EITHER PARTY TO THE OTHER FOR ANY DIRECT DAMAGES ARISING FROM OR RELATED TO THE SERVICES OR THIS AGREEMENT SHALL NOT EXCEED THE THE AMOUNT OF FEES AND OTHER CHARGES PAID OR PAYABLE BY SUBSCRIBER DURING THE TWELVE MONTH PERIOD PRECEDING THE FIRST EVENT GIVING RISE TO SUCH CLAIM.
This Agreement shall remain in effect while any performance by either party remains to be completed under any Order Form, subject to termination in accordance with subsection 11.2. Except as otherwise expressly provided in any Order Form, upon termination of this Agreement, all Services shall cease and Subscriber and Subscriber's Users will discontinue use of the Services and Website; provided, however, that OfficeRnD will allow Subscriber to remove Content from the Services for a period of 30 days following termination of this Agreement for any reason other than Subscriber's breach.
Either party may terminate this Agreement immediately upon written notice if the other party: (i) becomes the subject of a petition in bankruptcy which is not withdrawn or dismissed within 60 days thereafter; (ii) makes an assignment for the benefit of creditors; or (iii) breaches any material obligation under this Agreement and fails to cure such breach within 30 days after delivery of notice thereof by the non-breaching party. Otherwise, Subscriber's contract can be canceled at any time with one month notice without penalty. In the event of account cancellation, you will have one month to export your data and close your account.
All Fees are payable in advance, either annually in advance or in accordance with any different payment terms as stated in the applicable Order Form. Subscriber shall pay all fees specified in all Order Forms hereunder. Once an Order Form is executed by Subscriber and accepted by OfficeRnD the Order and payment obligations thereunder are non-cancellable, and fees paid are non-refundable unless specified otherwise in this Agreement. Failure to pay OfficeRnD the agreed amount within the agreed payment terms may result in the Services being made unavailable to Subscriber or legal action being taken to secure any outstanding fees. Subscriber shall also be liable for any additional costs, including legal costs, incurred by OfficeRnD to secure such fees.
Fees stated on Order Forms exclude any applicable sales and use taxes, value added tax or other taxes relating to provision or use of the Services. Subscriber is responsible for the payment of all such taxes (excluding taxes on OfficeRnD's income) and taxes applicable to the territory the Subscriber resides in.
Orders can be paid by bank transfer, check or credit or debit card. If you provide OfficeRnD with debit or credit card details, you authorise OfficeRnD to charge such debit or credit card for all fees listed in the Order Form as soon as practicable by OfficeRnD.
Unless paid for by debit or credit card, fees are payable 30 days from invoice date, unless alternative, agreed terms are stated on the Order Form and Subscriber is responsible for providing OfficeRnD with complete and accurate billing and contact information and notifying OfficeRnD of any changes to such information.
If any amount owing by Subscriber under an Order is 30 or more days overdue (or 10 or more days overdue in the case of Orders Subscriber has authorised OfficeRnD to charge Subscriber's debit or Credit card), OfficeRnD may, without limiting Our other rights and remedies, suspend Subscriber's account and Subscriber's Users' access to the Services until such amounts owing are paid in full.
Modification. OfficeRnD reserve the right to amend this Agreement at any time by notifying Subscriber as provided in this Agreement, provided that no notice shall be required for non-substantive changes to the Agreement. If OfficeRnD substantively amend this Agreement, OfficeRnD will post the updated Agreement on the website at least seven (7) days notice before the the changes take effect during which period of time you may reject the changes by terminating your account. If Subscriber does not agree to any of these terms or any future Agreement, then Subscriber is not to use or access (or continue to access) the Services or Website. No failure or delay by either party in exercising any right, power, or remedy hereunder shall operate as a waiver of such right, power, or remedy.
Remedies. The provisions of this Agreement are necessary for the protection of the business and goodwill of the parties and are considered by the parties to be reasonable for such purpose. Subscriber agrees that any breach of this Agreement may cause OfficeRnD substantial and irreparable damages and, therefore, in the event of any such breach, in addition to other remedies which may be available, OfficeRnD shall have the right to seek specific performance and other injunctive and equitable relief. In the event that Subscriber use the Services or Website for commercial purposes in breach of this Agreement, Subscriber agrees that OfficeRnD shall be entitled to any proceeds that Subscriber has obtained from such activity, without prejudice to other rights or remedies OfficeRnD may have against Subscriber.
Independent Contractors; No Third Party Beneficiaries. The parties are independent contractors with respect to each other, and neither shall be deemed an employee, agent, partner or legal representative of the other for any purpose or shall have any authority to create any obligation on behalf of the other. No third-party beneficiary rights are granted as a result of or pursuant to this Agreement.
Force Majeure. Any delay in or failure of performance by either party under this Agreement will not be considered a breach and will be excused to the extent caused by any event beyond the reasonable control of such party including, but not limited to, acts of God, acts of civil or military authorities, strikes or other labor disputes, fires, interruptions in telecommunications or Internet or network provider services, power outages, and governmental restrictions.
Entire Agreement; Severability. This Agreement supersedes all prior agreements, understandings, representations, warranties, proposals, requests for proposal and negotiations, if any, related to the subject matter hereof. Each provision of this Agreement is severable from each other provision for the purpose of determining the enforceability of any specific provision. This Section 13 shall survive termination or expiration of this Agreement.
Assignment. Except as otherwise provided below, neither party may assign this Agreement or any rights or obligations hereunder without the prior written consent of the other party. Either party shall have the right to assign this Agreement without the consent of the other party: (a) to any affiliate of such party; or (b) in connection with the merger, reorganization or acquisition of such party or the sale of all or substantially all of its assets related to this Agreement. Any purported assignment of this Agreement in violation of this subsection shall be invalid. This Agreement shall be binding upon and inure to the benefit of the parties, their respective successors and permitted assigns.
Notices. Invoices and other correspondence relating to this Agreement may be delivered by email to the email addresses furnished by Subscriber in each Order Form. Any notice of termination, breach or Actions under this Agreement shall be given by either email or internationally recognised courier service to the addresses set forth in the applicable Order Form or such other address as either party may provide in writing from time to time.
Subscriber is contracting with OFFICERND Limited, a company organized under the laws of the United Kingdom with offices located at Anova House Wickhurst Lane Broadbridge Heath Horsham West Sussex RH12 3LZ. and this Agreement shall be governed by and construed in accordance with the Law of England & Wales without giving effect to its conflict of laws principles. The parties agree the United Nations Convention on Contracts for the International Sale of Goods does not apply to this Agreement. The parties agree to submit to the jurisdiction of the Courts of England & Wales, for the adjudication of any case or controversy arising under this Agreement, and the parties hereby waive their right to a trial by jury in any such litigation.


text:
Q: Confusing JavaScript libraries I am building my first mobile app with HTML5/Javascript/CSS. I am feeling overwhelmed by number of JavaScript libraries out there. In short time that I spent; I came across JsRender, nodeJS, backbonejs, knockoutjs, TypeScript, CoffeeScript, Jquery... Is there a generally accepted as a "Best Practice" document for building mobile apps? So that I don't have to read about each of these libraries and figure out what I should and shouldn't use.
I guess this might not qualify as a specific enough question, but I couldn't find better forum to ask.

A: First of all, the JS libraries that you mention have each a different purpose.

*

*JsRender is for jQuery templating

*nodeJS is a JavaScript server

*Backbone is a JS library for applications client side built following the MVC pattern

*Knockout is a JS library for applications client side built following the MVVM pattern

*TypeScript and CoffeeScript are JS precompilers (allowing you to write code "easier", which compiles to JS)

I don't think there is any "best practice" here, since they all serve a different purpose. Learn their differences, pick one and go with it.
If you want to build a mobile app, I would suggest jQuery Mobile (but once again, that's a personal favorite). Others include Sencha Touch, Kendo UI Mobile, PhoneGap, ...

redpajama_set_name: RedPajamaStackExchange