<commit_before>/*
 *
 * * Copyright 2015 Acrolinx GmbH
 * *
 * * Licensed under the Apache License, Version 2.0 (the "License");
 * * you may not use this file except in compliance with the License.
 * * You may obtain a copy of the License at
 * *
 * * http://www.apache.org/licenses/LICENSE-2.0
 * *
 * * Unless required by applicable law or agreed to in writing, software
 * * distributed under the License is distributed on an "AS IS" BASIS,
 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * * See the License for the specific language governing permissions and
 * * limitations under the License.
 * *
 * * For more information visit: http://www.acrolinx.com
 *
 */

/*global rangy */

(function () {
  'use strict';

  var CLIENT_COMPONENTS = [
    {
      id: 'com.acrolinx.sidebarexample',
      name: 'Acrolinx Sidebar Example Client',
      version: '1.2.3.999',
      category: 'MAIN'
    }
  ];

  function initAcrolinxSamplePlugin(config) {
    var currentHtmlChecking;
    var lastCheckedHtml;
    var $sidebarContainer = $('#' + config.sidebarContainerId);
    var $sidebar = $('');
    $sidebarContainer.append($sidebar);
    var sidebarContentWindow = $sidebar.get(0).contentWindow;

    function getEditor() {
      return document.getElementById(config.editorId);
    }

    function getEditorElement() {
      return getEditor();
    }

    function getCurrentText() {
      return rangy.innerText(getEditorElement());
    }

    function getHTML() {
      return getEditor().innerHTML;
    }

    function selectText(begin, length) {
      /*
       * The DOM does not allow you to select text with offsets easily, but Rangy provides an implementation for that.
       * If you run into performance problems you should use another implementation.
       */
      var editorElement = getEditorElement();
      var r = rangy.createRange();
      r.setStart(editorElement, 0);
      r.setEnd(editorElement, 0);
      r.moveStart('character', begin);
      r.moveEnd('character', length);
      var sel = rangy.getSelection();
      sel.setSingleRange(r);
    }

    function findRangesPositionInPlainText(text, matches) {
      /*
       Be aware that matches can be discontinuous. Check if(matches[i].range[1] == matches[i+1].range[0]).
       An implementation for production use should store the last checked document content in a variable and look up the range offsets in the original document.
       Afterwards, it should map these offsets to the actual offsets of document. Due to changes in the document, the offsets might differ.
       */
      var rangesText = matches.map(function (match) {
        return match.content;
      }).join('');
      var indexOfRangesText = text.indexOf(rangesText);
      if (indexOfRangesText > -1) {
        return {
          start: indexOfRangesText,
          length: rangesText.length
        };
      } else {
        return null;
      }
    }

    function onSidebarLoaded () {
      function initSidebarCloud() {
        config.requestAccessTokenCallback(function (accessToken) {
          sidebarContentWindow.acrolinxSidebar.init({
            clientComponents: CLIENT_COMPONENTS,
            token: accessToken,
            contentPieceUuid: config.documentId,
            integrationFacadeBaseUrl: config.integrationFacadeBaseUrl

            // These settings are currently only supported by the sidebar on premise (and disabled checking profiles).
            //checkSettings: {
            //  'language': 'en',
            //  'ruleSetName': 'Plain English',
            //  'termSets': ['Medical'],
            //  'checkSpelling': true,
            //  'checkGrammar': true,
            //  'checkStyle': true,
            //  'checkReuse': false,
            //  'harvestTerms': false,
            //  'checkSeo': false,
            //  'termStatuses': ['TERMINOLOGY_DEPRECATED']
            //}

            // These settings are currently only supported by the sidebar on premise (and disabled checking profiles).
            //defaultCheckSettings: {
            //  'language': 'en',
            //  'ruleSetName': 'Plain English',
            //  'termSets': ['Medical'],
            //  'checkSpelling': true,
            //  'checkGrammar': true,
            //  'checkStyle': true,
            //  'checkReuse': false,
            //  'harvestTerms': false,
            //  'checkSeo': false,
            //  'termStatuses': ['TERMINOLOGY_DEPRECATED']
            //}

          });
        });
      }

      function initSidebarOnPremise() {
        sidebarContentWindow.acrolinxSidebar.init({
          clientComponents: CLIENT_COMPONENTS,
          clientSignature: config.clientSignature,
          showServerSelector: true,
          serverAddress: config.serverAddress
        });
      }

      console.log('Install acrolinxPlugin in sidebar.');
      sidebarContentWindow.acrolinxPlugin = {

        requestInit: function () {
          console.log('requestInit');
          if (config.sidebarType === 'CLOUD') {
            initSidebarCloud();
          } else {
            initSidebarOnPremise();
          }
        },

        onInitFinished: function (initFinishedResult) {
          console.log('onInitFinished: ', initFinishedResult);
          if (initFinishedResult.error) {
            window.alert(initFinishedResult.error.message);
          }
        },

        configure: function (configuration) {
          console.log('configure: ', configuration);
        },

        requestAccessToken: function () {
          var requestAccessTokenCallback = config.requestAccessTokenCallback;
          if (requestAccessTokenCallback) {
            requestAccessTokenCallback(function (accessToken) {
              sidebarContentWindow.acrolinxSidebar.setAccessToken(accessToken);
            });
          }
        },

        requestGlobalCheck: function () {
          console.log('requestGlobalCheck');
          var html = getHTML().trim();
          var checkInfo = sidebarContentWindow.acrolinxSidebar.checkGlobal(html, {
            inputFormat: 'HTML',
            requestDescription: {
              documentReference: 'filename.html'
            }
          });
          console.log('Got checkId:', checkInfo.checkId);
          currentHtmlChecking = html;
        },

        onCheckResult: function (checkResult) {
          console.log('onCheckResult: ', checkResult);
          lastCheckedHtml = currentHtmlChecking;
          return [];
        },

        selectRanges: function (checkId, matches) {
          console.log('selectRanges: ', checkId, matches);
          var positionInPlainText = findRangesPositionInPlainText(getCurrentText(), matches);
          if (positionInPlainText) {
            selectText(positionInPlainText.start, positionInPlainText.length);
            // In a complete plugin we should also scroll to the selected text.
          } else {
            window.alert('Sorry, but I can\'t select this issue.');
          }
        },

        replaceRanges: function (checkId, matchesWithReplacement) {
          console.log('replaceRanges: ', checkId, matchesWithReplacement);
          this.selectRanges(checkId, matchesWithReplacement);
          var replacementText = matchesWithReplacement.map(function (matcheWithReplacement) {
            return matcheWithReplacement.replacement;
          }).join('');
          var sel = rangy.getSelection();
          var range = sel.getRangeAt(0);
          range.deleteContents();
          var node = range.createContextualFragment(replacementText);
          range.insertNode(node);
        },

        // only needed for local checks
        getRangesOrder: function (checkedDocumentRanges) {
          console.log('getRangesOrder: ', checkedDocumentRanges);
          return [];
        },

        download: function (download) {
          console.log('download: ', download.url, download);
          window.open(download.url);
        },

        // only needed for local checks
        verifyRanges: function (checkedDocumentParts) {
          console.log('verifyRanges: ', checkedDocumentParts);
          return [];
        },

        disposeCheck: function (checkId) {
          console.log('disposeCheck: ', checkId);
        }
      };
    }

    function loadSidebarIntoIFrame() {
      var sidebarBaseUrl = config.sidebarType === 'CLOUD'?
        'https://acrolinx-integrations.acrolinx-cloud.com/sidebar/v13/' :
        'https://acrolinx-sidebar-classic.s3.amazonaws.com/v13/prod/';
      return $.ajax({
        url: sidebarBaseUrl + 'index.html',
      }).then(function (sidebarHtml) {
        var sidebarHtmlWithAbsoluteLinks = sidebarHtml
          .replace(/src="/g, 'src="' + sidebarBaseUrl)
          .replace(/href="/g, 'href="' + sidebarBaseUrl);
        sidebarContentWindow.document.open();
        sidebarContentWindow.document.write(sidebarHtmlWithAbsoluteLinks);
        sidebarContentWindow.document.close();
        onSidebarLoaded();
      });
    }

    loadSidebarIntoIFrame();
  }

  window.initAcrolinxSamplePlugin = initAcrolinxSamplePlugin;

})();

<commit_msg>DEV-683: CKEditor Admin / Integrator Needs to Set Default Checking Settings https://acrolinx.atlassian.net/browse/DEV-683<commit_after>/*
 *
 * * Copyright 2015 Acrolinx GmbH
 * *
 * * Licensed under the Apache License, Version 2.0 (the "License");
 * * you may not use this file except in compliance with the License.
 * * You may obtain a copy of the License at
 * *
 * * http://www.apache.org/licenses/LICENSE-2.0
 * *
 * * Unless required by applicable law or agreed to in writing, software
 * * distributed under the License is distributed on an "AS IS" BASIS,
 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * * See the License for the specific language governing permissions and
 * * limitations under the License.
 * *
 * * For more information visit: http://www.acrolinx.com
 *
 */

/*global rangy */

(function () {
  'use strict';

  var CLIENT_COMPONENTS = [
    {
      id: 'com.acrolinx.sidebarexample',
      name: 'Acrolinx Sidebar Example Client',
      version: '1.2.3.999',
      category: 'MAIN'
    }
  ];

  function initAcrolinxSamplePlugin(config) {
    var currentHtmlChecking;
    var lastCheckedHtml;
    var $sidebarContainer = $('#' + config.sidebarContainerId);
    var $sidebar = $('');
    $sidebarContainer.append($sidebar);
    var sidebarContentWindow = $sidebar.get(0).contentWindow;

    function getEditor() {
      return document.getElementById(config.editorId);
    }

    function getEditorElement() {
      return getEditor();
    }

    function getCurrentText() {
      return rangy.innerText(getEditorElement());
    }

    function getHTML() {
      return getEditor().innerHTML;
    }

    function selectText(begin, length) {
      /*
       * The DOM does not allow you to select text with offsets easily, but Rangy provides an implementation for that.
       * If you run into performance problems you should use another implementation.
       */
      var editorElement = getEditorElement();
      var r = rangy.createRange();
      r.setStart(editorElement, 0);
      r.setEnd(editorElement, 0);
      r.moveStart('character', begin);
      r.moveEnd('character', length);
      var sel = rangy.getSelection();
      sel.setSingleRange(r);
    }

    function findRangesPositionInPlainText(text, matches) {
      /*
       Be aware that matches can be discontinuous. Check if(matches[i].range[1] == matches[i+1].range[0]).
       An implementation for production use should store the last checked document content in a variable and look up the range offsets in the original document.
       Afterwards, it should map these offsets to the actual offsets of document. Due to changes in the document, the offsets might differ.
       */
      var rangesText = matches.map(function (match) {
        return match.content;
      }).join('');
      var indexOfRangesText = text.indexOf(rangesText);
      if (indexOfRangesText > -1) {
        return {
          start: indexOfRangesText,
          length: rangesText.length
        };
      } else {
        return null;
      }
    }

    function onSidebarLoaded () {
      function initSidebarCloud() {
        config.requestAccessTokenCallback(function (accessToken) {
          sidebarContentWindow.acrolinxSidebar.init({
            clientComponents: CLIENT_COMPONENTS,
            token: accessToken,
            contentPieceUuid: config.documentId,
            integrationFacadeBaseUrl: config.integrationFacadeBaseUrl
          });
        });
      }

      function initSidebarOnPremise() {
        sidebarContentWindow.acrolinxSidebar.init({
          clientComponents: CLIENT_COMPONENTS,
          clientSignature: config.clientSignature,
          showServerSelector: true,
          serverAddress: config.serverAddress

          // These settings are only effective on servers with disabled checking profiles.
          //checkSettings: {
          //  'language': 'en',
          //  'ruleSetName': 'Plain English',
          //  'termSets': ['Medical'],
          //  'checkSpelling': true,
          //  'checkGrammar': true,
          //  'checkStyle': true,
          //  'checkReuse': false,
          //  'harvestTerms': false,
          //  'checkSeo': false,
          //  'termStatuses': ['TERMINOLOGY_DEPRECATED']
          //}

          // These settings are only effective on servers with disabled checking profiles.
          //defaultCheckSettings: {
          //  'language': 'en',
          //  'ruleSetName': 'Plain English',
          //  'termSets': ['Medical'],
          //  'checkSpelling': true,
          //  'checkGrammar': true,
          //  'checkStyle': true,
          //  'checkReuse': false,
          //  'harvestTerms': false,
          //  'checkSeo': false,
          //  'termStatuses': ['TERMINOLOGY_DEPRECATED']
          //}

        });
      }

      console.log('Install acrolinxPlugin in sidebar.');
      sidebarContentWindow.acrolinxPlugin = {

        requestInit: function () {
          console.log('requestInit');
          if (config.sidebarType === 'CLOUD') {
            initSidebarCloud();
          } else {
            initSidebarOnPremise();
          }
        },

        onInitFinished: function (initFinishedResult) {
          console.log('onInitFinished: ', initFinishedResult);
          if (initFinishedResult.error) {
            window.alert(initFinishedResult.error.message);
          }
        },

        configure: function (configuration) {
          console.log('configure: ', configuration);
        },

        requestAccessToken: function () {
          var requestAccessTokenCallback = config.requestAccessTokenCallback;
          if (requestAccessTokenCallback) {
            requestAccessTokenCallback(function (accessToken) {
              sidebarContentWindow.acrolinxSidebar.setAccessToken(accessToken);
            });
          }
        },

        requestGlobalCheck: function () {
          console.log('requestGlobalCheck');
          var html = getHTML().trim();
          var checkInfo = sidebarContentWindow.acrolinxSidebar.checkGlobal(html, {
            inputFormat: 'HTML',
            requestDescription: {
              documentReference: 'filename.html'
            }
          });
          console.log('Got checkId:', checkInfo.checkId);
          currentHtmlChecking = html;
        },

        onCheckResult: function (checkResult) {
          console.log('onCheckResult: ', checkResult);
          lastCheckedHtml = currentHtmlChecking;
          return [];
        },

        selectRanges: function (checkId, matches) {
          console.log('selectRanges: ', checkId, matches);
          var positionInPlainText = findRangesPositionInPlainText(getCurrentText(), matches);
          if (positionInPlainText) {
            selectText(positionInPlainText.start, positionInPlainText.length);
            // In a complete plugin we should also scroll to the selected text.
          } else {
            window.alert('Sorry, but I can\'t select this issue.');
          }
        },

        replaceRanges: function (checkId, matchesWithReplacement) {
          console.log('replaceRanges: ', checkId, matchesWithReplacement);
          this.selectRanges(checkId, matchesWithReplacement);
          var replacementText = matchesWithReplacement.map(function (matcheWithReplacement) {
            return matcheWithReplacement.replacement;
          }).join('');
          var sel = rangy.getSelection();
          var range = sel.getRangeAt(0);
          range.deleteContents();
          var node = range.createContextualFragment(replacementText);
          range.insertNode(node);
        },

        // only needed for local checks
        getRangesOrder: function (checkedDocumentRanges) {
          console.log('getRangesOrder: ', checkedDocumentRanges);
          return [];
        },

        download: function (download) {
          console.log('download: ', download.url, download);
          window.open(download.url);
        },

        // only needed for local checks
        verifyRanges: function (checkedDocumentParts) {
          console.log('verifyRanges: ', checkedDocumentParts);
          return [];
        },

        disposeCheck: function (checkId) {
          console.log('disposeCheck: ', checkId);
        }
      };
    }

    function loadSidebarIntoIFrame() {
      var sidebarBaseUrl = config.sidebarType === 'CLOUD'?
        'https://acrolinx-integrations.acrolinx-cloud.com/sidebar/v13/' :
        'https://acrolinx-sidebar-classic.s3.amazonaws.com/v13/prod/';
      return $.ajax({
        url: sidebarBaseUrl + 'index.html',
      }).then(function (sidebarHtml) {
        var sidebarHtmlWithAbsoluteLinks = sidebarHtml
          .replace(/src="/g, 'src="' + sidebarBaseUrl)
          .replace(/href="/g, 'href="' + sidebarBaseUrl);
        sidebarContentWindow.document.open();
        sidebarContentWindow.document.write(sidebarHtmlWithAbsoluteLinks);
        sidebarContentWindow.document.close();
        onSidebarLoaded();
      });
    }

    loadSidebarIntoIFrame();
  }

  window.initAcrolinxSamplePlugin = initAcrolinxSamplePlugin;

})();

<|endoftext|>


<commit_before>import React from 'react'
import styled from 'styled-components'
import { useTable, usePagination } from 'react-table'

import makeData from './makeData'

const Styles = styled.div`
  padding: 1rem;

  table {
    border-spacing: 0;
    border: 1px solid black;

    tr {
      :last-child {
        td {
          border-bottom: 0;
        }
      }
    }

    th,
    td {
      margin: 0;
      padding: 0.5rem;
      border-bottom: 1px solid black;
      border-right: 1px solid black;

      :last-child {
        border-right: 0;
      }
    }
  }

  .pagination {
    padding: 0.5rem;
  }
`

// Let's add a fetchData method to our Table component that will be used to fetch
// new data when pagination state changes
// We can also add a loading state to let our table know it's loading new data
function Table({
  columns,
  data,
  fetchData,
  loading,
  pageCount: controlledPageCount,
}) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    // Get the state from the instance
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data,
      state: { pageIndex: 0 }, // Pass our hoisted table state
      manualPagination: true, // Tell the usePagination
      // hook that we'll handle our own data fetching
      // This means we'll also have to provide our own
      // pageCount.
      pageCount: controlledPageCount,
    },
    usePagination
  )

  // Now we can get our table state from the hoisted table state tuple

  // Listen for changes in pagination and use the state to fetch our new data
  React.useEffect(() => {
    fetchData({ pageIndex, pageSize })
  }, [fetchData, pageIndex, pageSize])

  // Render the UI for your table
  return (
    <>

          {JSON.stringify(
            {
              pageIndex,
              pageSize,
              pageCount,
              canNextPage,
              canPreviousPage,
            },
            null,
            2
          )}

          {headerGroups.map(headerGroup => (

              {headerGroup.headers.map(column => (
                {column.render('Header')}
              ))}

          ))}

          {page.map(
            (row, i) =>
              prepareRow(row) || (

                  {row.cells.map(cell => {
                    return (
                      {cell.render('Cell')}
                    )
                  })}

              )
          )}
          {loading ? (
            // Use our custom loading state to show a loading indicator

              Loading...

          ) : null}

      {/*
        Pagination can be built however you'd like.
        This is just a very basic UI implementation:
      */}

        <button onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
          {'<<'}
        </button>{' '}
        <button onClick={() => previousPage()} disabled={!canPreviousPage}>
          {'<'}
        </button>{' '}
        <button onClick={() => nextPage()} disabled={!canNextPage}>
          {'>'}
        </button>{' '}
        <button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
          {'>>'}
        </button>{' '}

          Page{' '}

            {pageIndex + 1} of {pageOptions.length}
          {' '}

          | Go to page:{' '}
          <input
            type="number"
            defaultValue={pageIndex + 1}
            onChange={e => {
              const page = e.target.value ? Number(e.target.value) - 1 : 0
              gotoPage(page)
            }}
            style={{ width: '100px' }}
          />
        {' '}
        <select
          value={pageSize}
          onChange={e => {
            setPageSize(Number(e.target.value))
          }}
        >
          {[10, 20, 30, 40, 50].map(pageSize => (
            <option key={pageSize} value={pageSize}>
              Show {pageSize}
            </option>
          ))}
        </select>

    </>
  )
}

// Let's simulate a large dataset on the server (outside of our component)
const serverData = makeData(10000)

function App() {
  const columns = React.useMemo(
    () => [
      {
        Header: 'Name',
        columns: [
          {
            Header: 'First Name',
            accessor: 'firstName',
          },
          {
            Header: 'Last Name',
            accessor: 'lastName',
          },
        ],
      },
      {
        Header: 'Info',
        columns: [
          {
            Header: 'Age',
            accessor: 'age',
          },
          {
            Header: 'Visits',
            accessor: 'visits',
          },
          {
            Header: 'Status',
            accessor: 'status',
          },
          {
            Header: 'Profile Progress',
            accessor: 'progress',
          },
        ],
      },
    ],
    []
  )

  // We'll start our table without any data
  const [data, setData] = React.useState([])
  const [loading, setLoading] = React.useState(false)
  const [pageCount, setPageCount] = React.useState(0)

  const fetchData = React.useCallback(({ pageSize, pageIndex }) => {
    // This will get called when the table needs new data
    // You could fetch your data from literally anywhere,
    // even a server. But for this example, we'll just fake it.

    // Set the loading state
    setLoading(true)

    // We'll even set a delay to simulate a server here
    setTimeout(() => {
      const startRow = pageSize * pageIndex
      const endRow = startRow + pageSize
      setData(serverData.slice(startRow, endRow))

      // Your server could send back total page count.
      // For now we'll just fake it, too
      setPageCount(Math.ceil(serverData.length / pageSize))

      setLoading(false)
    }, 1000)
  }, [])

  return (

  )
}

export default App
<commit_msg>Update controlled pagination example<commit_after>import React from "react";
import styled from "styled-components";
import { useTable, usePagination } from "react-table";

import makeData from "./makeData";

const Styles = styled.div`
  padding: 1rem;

  table {
    border-spacing: 0;
    border: 1px solid black;

    tr {
      :last-child {
        td {
          border-bottom: 0;
        }
      }
    }

    th,
    td {
      margin: 0;
      padding: 0.5rem;
      border-bottom: 1px solid black;
      border-right: 1px solid black;

      :last-child {
        border-right: 0;
      }
    }
  }

  .pagination {
    padding: 0.5rem;
  }
`;

// Let's add a fetchData method to our Table component that will be used to fetch
// new data when pagination state changes
// We can also add a loading state to let our table know it's loading new data
function Table({
  columns,
  data,
  fetchData,
  loading,
  pageCount: controlledPageCount
}) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    rows,
    // Get the state from the instance
    state: { pageIndex, pageSize }
  } = useTable(
    {
      columns,
      data,
      initialState: { pageIndex: 0 }, // Pass our hoisted table state
      manualPagination: true, // Tell the usePagination
      // hook that we'll handle our own data fetching
      // This means we'll also have to provide our own
      // pageCount.
      pageCount: controlledPageCount
    },
    usePagination
  );

  // Now we can get our table state from the hoisted table state tuple

  // Listen for changes in pagination and use the state to fetch our new data
  React.useEffect(() => {
    console.log(pageIndex);
    fetchData({ pageIndex, pageSize });
  }, [fetchData, pageIndex, pageSize]);

  // Render the UI for your table
  return (
    <>

          {JSON.stringify(
            {
              pageIndex,
              pageSize,
              pageCount,
              canNextPage,
              canPreviousPage
            },
            null,
            2
          )}

          {headerGroups.map(headerGroup => (

              {headerGroup.headers.map(column => (
                {column.render("Header")}
              ))}

          ))}

          {page.map(
            (row, i) =>
              prepareRow(row) || (

                  {row.cells.map(cell => {
                    return (
                      {cell.render("Cell")}
                    );
                  })}

              )
          )}

            {loading ? (
              // Use our custom loading state to show a loading indicator
              Loading...
            ) : (

                Showing {page.length} of ~{controlledPageCount * pageSize}{" "}
                results

            )}

      {/*
        Pagination can be built however you'd like.
        This is just a very basic UI implementation:
      */}

        <button onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
          {"<<"}
        </button>{" "}
        <button onClick={() => previousPage()} disabled={!canPreviousPage}>
          {"<"}
        </button>{" "}
        <button onClick={() => nextPage()} disabled={!canNextPage}>
          {">"}
        </button>{" "}
        <button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
          {">>"}
        </button>{" "}

          Page{" "}

            {pageIndex + 1} of {pageOptions.length}
          {" "}

          | Go to page:{" "}
          <input
            type="number"
            defaultValue={pageIndex + 1}
            onChange={e => {
              const page = e.target.value ? Number(e.target.value) - 1 : 0;
              gotoPage(page);
            }}
            style={{ width: "100px" }}
          />
        {" "}
        <select
          value={pageSize}
          onChange={e => {
            setPageSize(Number(e.target.value));
          }}
        >
          {[10, 20, 30, 40, 50].map(pageSize => (
            <option key={pageSize} value={pageSize}>
              Show {pageSize}
            </option>
          ))}
        </select>

    </>
  );
}

// Let's simulate a large dataset on the server (outside of our component)
const serverData = makeData(10000);

function App() {
  const columns = React.useMemo(
    () => [
      {
        Header: "Name",
        columns: [
          {
            Header: "First Name",
            accessor: "firstName"
          },
          {
            Header: "Last Name",
            accessor: "lastName"
          }
        ]
      },
      {
        Header: "Info",
        columns: [
          {
            Header: "Age",
            accessor: "age"
          },
          {
            Header: "Visits",
            accessor: "visits"
          },
          {
            Header: "Status",
            accessor: "status"
          },
          {
            Header: "Profile Progress",
            accessor: "progress"
          }
        ]
      }
    ],
    []
  );

  // We'll start our table without any data
  const [data, setData] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [pageCount, setPageCount] = React.useState(0);

  const fetchData = React.useCallback(({ pageSize, pageIndex }) => {
    // This will get called when the table needs new data
    // You could fetch your data from literally anywhere,
    // even a server. But for this example, we'll just fake it.

    // Set the loading state
    setLoading(true);

    // We'll even set a delay to simulate a server here
    setTimeout(() => {
      const startRow = pageSize * pageIndex;
      const endRow = startRow + pageSize;
      setData(serverData.slice(startRow, endRow));

      // Your server could send back total page count.
      // For now we'll just fake it, too
      setPageCount(Math.ceil(serverData.length / pageSize));

      setLoading(false);
    }, 1000);
  }, []);

  return (

  );
}

export default App;
<|endoftext|>


<commit_before>define([
	'jquery'
	, 'backbone'
	, 'app'
], function ($, Backbone, App) {
    var Model = Backbone.Model.extend({
		defaults: function() {
			var secrets;
			try {
				secrets = JSON.parse(this.getSecrets());
			} catch(exception) {
				console.error('Error with JSON.parse(this.getSecrets())');
				console.error(exception);

				secrets = undefined;
			}

			return {
				id: 1
				, env: 'local'
				, app: 'james'
				, backend: 'backend'
				, datePickerConf: {
					dateFormat: 'dd/mm/yy',
					dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado'],
					dayNamesMin: ['D','S','T','Q','Q','S','S','D'],
					dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb','Dom'],
					monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
					monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'],
					nextText: 'Próximo',
					prevText: 'Anterior',
					changeMonth: true,
					changeYear: true,
					yearRange: (new Date().getFullYear() - 100) + ':' + (new Date().getFullYear() + 100)
				}
				, isProtected: false
				, timesheet: {
					id: 1 // FIXME is used?
					, startTime: '08:00'
					, endTime: '14:00'
					, workload: '06:00'
					, timesheetBackendURL: (secrets && typeof secrets === 'object') ? secrets.timesheet.timesheetBackendURL : 'BACKEND_HERE'
				}
				, cloudAuth: {
					email: (secrets && typeof secrets === 'object') ? secrets.cloudAuth.email : '<YOUR_EMAIL_HERE>@<SOME_DOMAIN>'
					, password: (secrets && typeof secrets === 'object') ? secrets.cloudAuth.password : '<YOUR_PASSWORD_HERE>'
				}
			};
		}

		/**
		 * It's a pain in... to always type configuration data that's secret (e.g.: password).
		 * So, instead of type, I saved it in app/data/secrets.json and add it to .gitignore.
		 * *Be careful* to not send this file with a public build of this app.
		 * By the way, I added the file secrets.json.example with instructions.
		 * Add your own data and save as secrets.json
		 * Again: *be careful* (very) to not add it with a public build. It would be sad. Very sad. :'(
		 *
		 */
		, getSecrets: function(file) {
			if (file == undefined)
				file = 'app/data/secrets.json';

			return $.ajax({
				type: 'GET',
				url: file,
				async: false
			}).responseText;
		}

		// TODO What to do if has no settings in storage?
		, getInfo: function(onSuccess) {
			var settings,
				objectStore = App.indexedDB.db.transaction(['settings'], 'readonly').objectStore('settings').get(1)
			;
			objectStore.onsuccess = onSuccess;
		}
    });

    return Model;
});
<commit_msg>Typo<commit_after>define([
	'jquery'
	, 'backbone'
	, 'app'
], function ($, Backbone, App) {
    var Model = Backbone.Model.extend({
		defaults: function() {
			var secrets;
			try {
				secrets = JSON.parse(this.getSecrets());
			} catch(exception) {
				console.error('Error with JSON.parse(this.getSecrets())');
				console.error(exception);

				secrets = undefined;
			}

			return {
				id: 1
				, env: 'local'
				, app: 'james'
				, backend: 'backend'
				, datePickerConf: {
					dateFormat: 'dd/mm/yy',
					dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado'],
					dayNamesMin: ['D','S','T','Q','Q','S','S','D'],
					dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb','Dom'],
					monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
					monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'],
					nextText: 'Próximo',
					prevText: 'Anterior',
					changeMonth: true,
					changeYear: true,
					yearRange: (new Date().getFullYear() - 100) + ':' + (new Date().getFullYear() + 100)
				}
				, isProtected: false
				, timesheet: {
					id: 1 // FIXME is used?
					, startTime: '08:00'
					, endTime: '14:00'
					, workload: '06:00'
					, timesheetBackendURL: (secrets && typeof secrets === 'object') ? secrets.timesheet.timesheetBackendURL : 'BACKEND_HERE'
				}
				, cloudAuth: {
					email: (secrets && typeof secrets === 'object') ? secrets.cloudAuth.email : '<YOUR_EMAIL_HERE>@<SOME_DOMAIN>'
					, password: (secrets && typeof secrets === 'object') ? secrets.cloudAuth.password : '<YOUR_PASSWORD_HERE>'
				}
			};
		}

		/**
		 * It's a pain in... to always type configuration data that's secret (e.g.: password).
		 * So, instead of type, I saved it in app/data/secrets.json and add it to .gitignore.
		 * *Be careful* to not send this file with a public build of this app.
		 * By the way, I added the file secrets.json.example with instructions.
		 * Add your own data and save as secrets.json
		 * Again: *be careful* (very) to not add it with a public build. It would be sad. Very sad. :'(
		 *
		 */
		, getSecrets: function(file) {
			if (file == undefined)
				file = 'app/data/secrets.json';

			return $.ajax({
				type: 'GET',
				url: file,
				async: false
			}).responseText;
		}

		, getInfo: function(onSuccess) {
			var settings,
				objectStore = App.indexedDB.db.transaction(['settings'], 'readonly').objectStore('settings').get(1)
			;
			objectStore.onsuccess = onSuccess;
		}
    });

    return Model;
});
<|endoftext|>


<commit_before>/*******************************************************************************
* Nome: QuizziPedia::Front-End::Controllers::HomeController;
* Description: questa classe permette di gestire la home page. Fornisce tutte
* le informazioni da mostrare nella homepage;
*
*
* Creation data: 25-04-2016;
* Author: Matteo Granzotto;
* License: MIT.
********************************************************************************
* Updates history
 *-------------------------------------------------------------------------------
 * ID: HomeView_20160509;
 * Update data: 09-05-2016;
 * Description: Completata la classe con la funzione search();
 * Author: Alberto Ferrara.
 *-------------------------------------------------------------------------------
* ID: HomeView_20160425;
* Update data: 25-04-2016;
* Description: Scritta la classe e il metodo trainingMode();
* Author: Matteo Granzotto.
*-------------------------------------------------------------------------------
*******************************************************************************/

app.controller('HomeController', HomeController);

HomeController.$inject = ['$scope','$location','$routeParams','ngMeta'];
function HomeController ($scope, $location, $routeParams,ngMeta) {
  if ($rootScope.listOfKeys!=undefined){
    metaData();
  }
  var langDownloaded = $rootScope.$on("langDownloaded", function(event, args) {
    if(args){
      metaData();
    }
  });
  $scope.$on('$destroy', langDownloaded);

  function metaData() {
    ngMeta.setTitle($rootScope.listOfKeys.home);
    ngMeta.setTag('description',$rootScope.listOfKeys.homeDescription);
  }
  $scope.trainingMode = function(){
    $location.path("/"+$routeParams.lang+"/training");
  };

  $scope.search = function(){
    var tosearch = document.getElementById("lookingfor").value;
    if(tosearch){
        $location.path("/" + $routeParams.lang + "/search/" + tosearch);
    }
  }
}
<commit_msg>updated quiz management<commit_after>/*******************************************************************************
* Nome: QuizziPedia::Front-End::Controllers::HomeController;
* Description: questa classe permette di gestire la home page. Fornisce tutte
* le informazioni da mostrare nella homepage;
*
*
* Creation data: 25-04-2016;
* Author: Matteo Granzotto;
* License: MIT.
********************************************************************************
* Updates history
 *-------------------------------------------------------------------------------
 * ID: HomeView_20160509;
 * Update data: 09-05-2016;
 * Description: Completata la classe con la funzione search();
 * Author: Alberto Ferrara.
 *-------------------------------------------------------------------------------
* ID: HomeView_20160425;
* Update data: 25-04-2016;
* Description: Scritta la classe e il metodo trainingMode();
* Author: Matteo Granzotto.
*-------------------------------------------------------------------------------
*******************************************************************************/

app.controller('HomeController', HomeController);

HomeController.$inject = ['$rootScope','$scope','$location','$routeParams','ngMeta'];
function HomeController ($rootScope,$scope, $location, $routeParams,ngMeta) {
  if ($rootScope.listOfKeys!=undefined){
    metaData();
  }
  var langDownloaded = $rootScope.$on("langDownloaded", function(event, args) {
    if(args){
      metaData();
    }
  });
  $scope.$on('$destroy', langDownloaded);

  function metaData() {
    ngMeta.setTitle($rootScope.listOfKeys.home);
    ngMeta.setTag('description',$rootScope.listOfKeys.homeDescription);
  }
  $scope.trainingMode = function(){
    $location.path("/"+$routeParams.lang+"/training");
  };

  $scope.search = function(){
    var tosearch = document.getElementById("lookingfor").value;
    if(tosearch){
        $location.path("/" + $routeParams.lang + "/search/" + tosearch);
    }
  }
}
<|endoftext|>


<commit_before>import { translate } from '../../../common/i18n';
import { tradeOptionToProposal, doUntilDone } from '../tools';
import { proposalsReady, clearProposals } from './state/actions';
import { TrackJSError } from '../../view/logger';

export default Engine =>
    class Proposal extends Engine {
        makeProposals(tradeOption) {
            if (!this.isNewTradeOption(tradeOption)) {
                return;
            }

            // Generate a purchase reference when trade options are different from previous trade options.
            // This will ensure the bot doesn't mistakenly purchase the wrong proposal.
            this.regeneratePurchaseReference();
            this.tradeOption = tradeOption;
            this.proposalTemplates = tradeOptionToProposal(tradeOption, this.getPurchaseReference());
            this.renewProposalsOnPurchase();
        }
        selectProposal(contractType) {
            const { proposals } = this.data;

            if (proposals.length === 0) {
                throw Error(translate('Proposals are not ready'));
            }

            const toBuy = proposals.find(proposal => {
                if (
                    proposal.contractType === contractType &&
                    proposal.purchaseReference === this.getPurchaseReference()
                ) {
                    if (proposal.error) {
                        const { error } = proposal.error.error;
                        const { code, message } = error;
                        throw new TrackJSError(code, message, error);
                    }

                    return proposal;
                }

                return false;
            });

            if (!toBuy) {
                throw new TrackJSError(
                    'CustomInvalidProposal',
                    translate('Selected proposal does not exist'),
                    this.data.proposals
                );
            }

            return {
                proposal: toBuy,
                currency: this.tradeOption.currency,
            };
        }
        renewProposalsOnPurchase() {
            this.unsubscribeProposals().then(() => this.requestProposals());
        }
        clearProposals() {
            this.data.proposals = [];
            this.store.dispatch(clearProposals());
        }
        requestProposals() {
            Promise.all(
                this.proposalTemplates.map(proposal =>
                    doUntilDone(() => this.api.subscribeToPriceForContractProposal(proposal))
                )
            ).catch(e => this.$scope.observer.emit('Error', e));
        }
        observeProposals() {
            this.listen('proposal', response => {
                const { passthrough, proposal } = response;

                if (
                    this.data.proposals.findIndex(p => p.id === proposal.id) === -1 &&
                    !this.data.forgetProposalIds.includes(proposal.id)
                ) {
                    // Add proposals based on the ID returned by the API.
                    this.data.proposals.push({ ...proposal, ...passthrough });
                    this.checkProposalReady();
                }
            });
        }
        unsubscribeProposals() {
            const { proposals } = this.data;
            const removeForgetProposalById = forgetProposalId => {
                this.data.forgetProposalIds = this.data.forgetProposalIds.filter(id => id !== forgetProposalId);
            };

            this.clearProposals();

            return Promise.all(
                proposals.map(proposal => {
                    if (!this.data.forgetProposalIds.includes(proposal.id)) {
                        this.data.forgetProposalIds.push(proposal.id);
                    }

                    if (proposal.error) {
                        removeForgetProposalById(proposal.id);
                        return Promise.resolve();
                    }

                    return doUntilDone(() => this.api.unsubscribeByID(proposal.id)).then(() =>
                        removeForgetProposalById(proposal.id)
                    );
                })
            );
        }
        checkProposalReady() {
            // Proposals are considered ready when the proposals in our memory match the ones
            // we've requested from the API, we determine this by checking the passthrough of the response.
            const { proposals } = this.data;

            if (proposals.length > 0) {
                const hasEqualLength = proposals.length === this.proposalTemplates.length;
                const hasEqualProposals = () =>
                    this.proposalTemplates.every(
                        template =>
                            proposals.findIndex(
                                proposal =>
                                    proposal.purchaseReference === template.passthrough.purchaseReference &&
                                    proposal.contractType === template.contract_type
                            ) !== -1
                    );

                if (hasEqualLength && hasEqualProposals()) {
                    this.startPromise.then(() => this.store.dispatch(proposalsReady()));
                }
            }
        }
        isNewTradeOption(tradeOption) {
            if (!this.tradeOption) {
                this.tradeOption = tradeOption;
                return true;
            }

            // Compare incoming "tradeOption" argument with "this.tradeOption", if any
            // of the values is different, this is a new tradeOption and new proposals
            // should be generated.
            return [
                'amount',
                'barrierOffset',
                'basis',
                'duration',
                'duration_unit',
                'prediction',
                'secondBarrierOffset',
                'symbol',
            ].some(value => this.tradeOption[value] !== tradeOption[value]);
        }
    };
<commit_msg>Handle ContractBuyValidationError<commit_after>import { translate } from '../../../common/i18n';
import { tradeOptionToProposal, doUntilDone } from '../tools';
import { proposalsReady, clearProposals } from './state/actions';
import { TrackJSError } from '../../view/logger';

export default Engine =>
    class Proposal extends Engine {
        makeProposals(tradeOption) {
            if (!this.isNewTradeOption(tradeOption)) {
                return;
            }

            // Generate a purchase reference when trade options are different from previous trade options.
            // This will ensure the bot doesn't mistakenly purchase the wrong proposal.
            this.regeneratePurchaseReference();
            this.tradeOption = tradeOption;
            this.proposalTemplates = tradeOptionToProposal(tradeOption, this.getPurchaseReference());
            this.renewProposalsOnPurchase();
        }
        selectProposal(contractType) {
            const { proposals } = this.data;

            if (proposals.length === 0) {
                throw Error(translate('Proposals are not ready'));
            }

            const toBuy = proposals.find(proposal => {
                if (
                    proposal.contractType === contractType &&
                    proposal.purchaseReference === this.getPurchaseReference()
                ) {
                    // Below happens when a user has had one of the proposals return
                    // with a ContractBuyValidationError. We allow the logic to continue
                    // to here cause the opposite proposal may still be valid. Only once
                    // they attempt to purchase the errored proposal we will intervene.
                    if (proposal.error) {
                        const { error } = proposal.error.error;
                        const { code, message } = error;
                        throw new TrackJSError(code, message, error);
                    }

                    return proposal;
                }

                return false;
            });

            if (!toBuy) {
                throw new TrackJSError(
                    'CustomInvalidProposal',
                    translate('Selected proposal does not exist'),
                    this.data.proposals
                );
            }

            return {
                proposal: toBuy,
                currency: this.tradeOption.currency,
            };
        }
        renewProposalsOnPurchase() {
            this.unsubscribeProposals().then(() => this.requestProposals());
        }
        clearProposals() {
            this.data.proposals = [];
            this.store.dispatch(clearProposals());
        }
        requestProposals() {
            Promise.all(
                this.proposalTemplates.map(proposal =>
                    doUntilDone(() =>
                        this.api.subscribeToPriceForContractProposal(proposal).catch(error => {
                            // We intercept ContractBuyValidationError as user may have specified
                            // e.g. a DIGITUNDER 0 or DIGITOVER 9, while one proposal may be invalid
                            // the other is valid. We will error on Purchase rather than here.
                            if (error && error.name === 'ContractBuyValidationError') {
                                this.data.proposals.push({
                                    ...error.error.echo_req,
                                    ...error.error.echo_req.passthrough,
                                    error,
                                });
                                return null;
                            }

                            throw error;
                        })
                    )
                )
            ).catch(e => this.$scope.observer.emit('Error', e));
        }
        observeProposals() {
            this.listen('proposal', response => {
                const { passthrough, proposal } = response;

                if (
                    this.data.proposals.findIndex(p => p.id === proposal.id) === -1 &&
                    !this.data.forgetProposalIds.includes(proposal.id)
                ) {
                    // Add proposals based on the ID returned by the API.
                    this.data.proposals.push({ ...proposal, ...passthrough });
                    this.checkProposalReady();
                }
            });
        }
        unsubscribeProposals() {
            const { proposals } = this.data;
            const removeForgetProposalById = forgetProposalId => {
                this.data.forgetProposalIds = this.data.forgetProposalIds.filter(id => id !== forgetProposalId);
            };

            this.clearProposals();

            return Promise.all(
                proposals.map(proposal => {
                    if (!this.data.forgetProposalIds.includes(proposal.id)) {
                        this.data.forgetProposalIds.push(proposal.id);
                    }

                    if (proposal.error) {
                        removeForgetProposalById(proposal.id);
                        return Promise.resolve();
                    }

                    return doUntilDone(() => this.api.unsubscribeByID(proposal.id)).then(() =>
                        removeForgetProposalById(proposal.id)
                    );
                })
            );
        }
        checkProposalReady() {
            // Proposals are considered ready when the proposals in our memory match the ones
            // we've requested from the API, we determine this by checking the passthrough of the response.
            const { proposals } = this.data;

            if (proposals.length > 0) {
                const hasEqualLength = proposals.length === this.proposalTemplates.length;
                const hasEqualProposals = () =>
                    this.proposalTemplates.every(
                        template =>
                            proposals.findIndex(
                                proposal =>
                                    proposal.purchaseReference === template.passthrough.purchaseReference &&
                                    proposal.contractType === template.contract_type
                            ) !== -1
                    );

                if (hasEqualLength && hasEqualProposals()) {
                    this.startPromise.then(() => this.store.dispatch(proposalsReady()));
                }
            }
        }
        isNewTradeOption(tradeOption) {
            if (!this.tradeOption) {
                this.tradeOption = tradeOption;
                return true;
            }

            // Compare incoming "tradeOption" argument with "this.tradeOption", if any
            // of the values is different, this is a new tradeOption and new proposals
            // should be generated.
            return [
                'amount',
                'barrierOffset',
                'basis',
                'duration',
                'duration_unit',
                'prediction',
                'secondBarrierOffset',
                'symbol',
            ].some(value => this.tradeOption[value] !== tradeOption[value]);
        }
    };
<|endoftext|>


<commit_before>/**
 * @ignore
 */
export function camelCase(value) {
    return value.toLowerCase().split('-').map((part, index) => index ? part.charAt(0).toUpperCase() + part.slice(1) : part).join('');
}

/**
 * @ignore
 */
export function isFunction(i) {
    return Object.prototype.toString.call(i) === '[object Function]';
}

/**
 * @ignore
 */
export function isUndefined(i) {
    return i === undefined;
}

/**
 * @ignore
 */
export function isNull(i) {
    return i === null;
}

/**
 * @ignore
 */
export function isString(i) {
    return Object.prototype.toString.call(i) === '[object String]';
}

/**
 * @ignore
 */
export function isArray(i) {
    return Object.prototype.toString.call(i) === '[object Array]';
}

/**
 * @ignore
 */
export function result(obj, prop) {
    let value = obj[prop];
    return isFunction(value) ? value() : value;
}

/**
 * @ignore
 */
export function assign() {
    return Array.prototype.reduce.call(arguments, function (target, source) {
        return Object.keys(Object(source)).reduce((target, key) => {
            target[key] = source[key];
            return target;
        }, target);
    });
}

/**
 * @ignore
 */
export function toArray(i) {
    return Array.prototype.slice.call(i);
}

/**
 * @ignore
 */
export function flatten(array) {
    return array.reduce((a, b) => isArray(b) ? a.concat(flatten(b)) : a.concat(b), []);
}

/**
 * @ignore
 */
export function invoke() {
    let args = toArray(arguments),
        objects = args.shift(),
        meth = args.shift();
    if (isArray(objects)) {
        objects.filter(obj => isFunction(obj[meth])).forEach(obj => obj[meth].apply(obj, args));
    }
}

/**
 * @ignore
 */
export function partial() {
    let args = toArray(arguments),
        fn = args.shift();
    return function () {
        return fn.apply(this, args.concat(toArray(arguments)));
    };
}

/**
 * @ignore
 */
export function bind(fn, ctx) {
    return function () {
        return fn.apply(ctx, toArray(arguments));
    };
}

/**
 * @ignore
 */
export function noop() {
    return function () {
    };
}

/**
 * @ignore
 */
export function find(array, cb) {
    return array.filter(cb)[0];
}

/**
 * @ignore
 */
export function dispatch(el, name, options = {}) {
    var evt = document.createEvent('CustomEvent');
    evt.initCustomEvent(
        name,
        options.bubbles !== false,
        options.cancelable !== false,
        options.detail || {}
    );
    return el.dispatchEvent(evt);
}
<commit_msg>refactor dispatch signature<commit_after>/**
 * @ignore
 */
export function camelCase(value) {
    return value.toLowerCase().split('-').map((part, index) => index ? part.charAt(0).toUpperCase() + part.slice(1) : part).join('');
}

/**
 * @ignore
 */
export function isFunction(i) {
    return Object.prototype.toString.call(i) === '[object Function]';
}

/**
 * @ignore
 */
export function isUndefined(i) {
    return i === undefined;
}

/**
 * @ignore
 */
export function isNull(i) {
    return i === null;
}

/**
 * @ignore
 */
export function isString(i) {
    return Object.prototype.toString.call(i) === '[object String]';
}

/**
 * @ignore
 */
export function isArray(i) {
    return Object.prototype.toString.call(i) === '[object Array]';
}

/**
 * @ignore
 */
export function result(obj, prop) {
    let value = obj[prop];
    return isFunction(value) ? value() : value;
}

/**
 * @ignore
 */
export function assign() {
    return Array.prototype.reduce.call(arguments, function (target, source) {
        return Object.keys(Object(source)).reduce((target, key) => {
            target[key] = source[key];
            return target;
        }, target);
    });
}

/**
 * @ignore
 */
export function toArray(i) {
    return Array.prototype.slice.call(i);
}

/**
 * @ignore
 */
export function flatten(array) {
    return array.reduce((a, b) => isArray(b) ? a.concat(flatten(b)) : a.concat(b), []);
}

/**
 * @ignore
 */
export function invoke() {
    let args = toArray(arguments),
        objects = args.shift(),
        meth = args.shift();
    if (isArray(objects)) {
        objects.filter(obj => isFunction(obj[meth])).forEach(obj => obj[meth].apply(obj, args));
    }
}

/**
 * @ignore
 */
export function partial() {
    let args = toArray(arguments),
        fn = args.shift();
    return function () {
        return fn.apply(this, args.concat(toArray(arguments)));
    };
}

/**
 * @ignore
 */
export function bind(fn, ctx) {
    return function () {
        return fn.apply(ctx, toArray(arguments));
    };
}

/**
 * @ignore
 */
export function noop() {
    return function () {
    };
}

/**
 * @ignore
 */
export function find(array, cb) {
    return array.filter(cb)[0];
}

/**
 * @ignore
 */
export function dispatch(el, name, options = {}, detail = undefined) {
    var evt = document.createEvent('CustomEvent');
    evt.initCustomEvent(
        name,
        options.bubbles !== false,
        options.cancelable !== false,
        detail
    );
    return el.dispatchEvent(evt);
}
<|endoftext|>


<commit_before>//
// Dynamo DB Interface
//

var AWS = require('aws-sdk');
AWS.config.update({
  accessKeyId:      process.env.S3_KEY,
  secretAccessKey:  process.env.S3_SECRET,
  region:           process.env.S3_REGION
});

//
// Response Helpers
//

function isEmpty(map) {
   for(var key in map) {
      if (map.hasOwnProperty(key)) {
         return false;
      }
   }
   return true;
}

function responseHelper(err, data, callback) {
  if (err) {
    console.log("** ERROR *********************************************");
    console.log(err, err.stack);
    callback(null);
    throw err;
  } else if (!(data instanceof Array) && isEmpty(data)) {
    callback(null);
  } else {
    callback(data);
  }
}

//
// Public Interface - Registrations
//

exports.allRegistrations = function() {
  // Not Implemented - Debug Only
  return {};
};

// Load Specific Registration
exports.getRegistration = function(registrationId, callback) {

  //console.log("getRegistration:" + registrationId);

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id: { 'S': registrationId }
    },
    TableName: 'xapi-registrations'
  }
  //console.log(params);

  dynamodb.getItem(params, function(err, data) {
    data = data ? data['Item'] : null;
    responseHelper(err, data, callback);
  });

};

exports.createRegistration = function(registrationId, callback) {

  //console.log("createRegistration");

  var data = { registrationId: registrationId };
  var dynamodb = new AWS.DynamoDB();
  var params = {
    Item: {
      registration_id: { 'S': registrationId }
    },
    TableName: 'xapi-registrations'
  }
  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, registrationId, callback);
  });

};

exports.deleteRegistration = function(registrationId, callback) {

  //console.log("deleteRegistration");

  var data = { registrationId: registrationId };
  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-registrations',
    Key: {
      registration_id: { 'S': registrationId }
    },
  }
  dynamodb.deleteItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

};

markRegistrationCompleted = function(registrationId, result, callback) {

  var data = { registrationId: registrationId };
  var dynamodb = new AWS.DynamoDB();
  var params = {
    Item: {
      registration_id: { 'S': registrationId },
      status:          { 'S': 'completed' },
      result:          { 'S': JSON.stringify(result) }
    },
    TableName: 'xapi-registrations'
  }
  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, registrationId, callback);
  });

};

//
// Public Interface - States
//

exports.getState = function(context, callback) {

  //console.log("getState");

  if (context.stateId==null || context.length==0) {
    throw "asdfasdfasdfsadf";
  }

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id:  { 'S': context.registrationId },
      state_id:         { 'S': context.stateId }
    },
    TableName: 'xapi-states'
  }
  //console.log(params);

  dynamodb.getItem(params, function(err, data) {
    data = data ? data['Item'] : null;
    data = data ? data['state_data'] : null;
    data = data ? data['S'] : null;
    responseHelper(err, data, callback);
  });

};

exports.getStateKeys = function(context, callback) {

  //console.log("getStateKeys");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-states',
    KeyConditions: {
      registration_id: {
        ComparisonOperator: 'EQ',
        AttributeValueList: [ { 'S': context.registrationId } ]
      }
    },
    AttributesToGet: [ 'state_id' ]
  }
  //console.log(params);

  dynamodb.query(params, function(err, data) {
    data = data ? data['Items'] : null;
    var keys = [];
    if (data) {
      for (var i=0; i<data.length; i++) {
        keys[i] = data[i]['state_id'];
        if (keys[i]['S']) {
          keys[i] = keys[i]['S'];
        }
      }
    }
    responseHelper(err, keys, callback);
  });

};

exports.setState = function(context, data, callback) {

  //console.log("setState");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Item: {
      registration_id: { 'S': context.registrationId },
      state_id:        { 'S': context.stateId },
      state_data:      { 'S': data }
    },
    TableName: 'xapi-states'
  }
  //console.log(params);

  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

};

exports.deleteState = function(context, callback) {

  //console.log("deleteState");

  if (context.stateId) {
    var dynamodb = new AWS.DynamoDB();
    var params = {
      Key: {
        registration_id:  { 'S': context.registrationId },
        state_id:         { 'S': context.stateId }
      },
      TableName: 'xapi-states'
    }
    //console.log(params);

    dynamodb.deleteItem(params, function(err, data) {
      responseHelper(err, data, callback);
    });

  } else {

    // Missing State Id - Delete all for registration per spec
    exports.getStateKeys(context, function(keys) {
      deleteStateList(context.registrationId, keys, callback);
    });

  }

};

//
// Public Interface - Statements
//

exports.getStatement = function(context, callback) {

  //console.log("getStatement");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id:  { 'S': context.registrationId },
      statement_id:     { 'S': context.statementId }
    },
    TableName: 'xapi-statements'
  }
  //console.log(params);

  dynamodb.getItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

};

exports.addStatement = function(context, data, callback) {

  console.log("addStatement");

  // Spec says to throw an error if already exists

  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-statements',
    Item: {
      registration_id: { 'S': context.registrationId },
      statement_id:    { 'S': context.statementId },
    }
    /* TODO ,
    Expected: { Exists: false }
    */
  }

  var verbName = data['verb'];
  var result = data['result']

  // Break into components
  for (var key in data) {
    if (data.hasOwnProperty(key)) {
      if (key=='verb') {
        params.Item[key] = { 'S': data[key] };
      } else {
        params.Item[key] = { 'S': JSON.stringify(data[key]) };
      }
    }
  }

  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, data, function(data) {

      // Check for completion?
      if (verbName=='completed') {
        markRegistrationCompleted(context.registrationId,result,function(not_used) {
          callback(data);
        });
      } else {
        callback(data);
      }

    });
  });

};

exports.findStatements = function(context, callback) {

  //console.log("findStatements");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-statements',
    KeyConditions: {
      registration_id: {
        ComparisonOperator: 'EQ',
        AttributeValueList: [ { 'S': context.registrationId } ]
      }
    }
  }
  //console.log(params);

  dynamodb.query(params, function(err, data) {
    data = data ? data['Items'] : null;
    responseHelper(err, data, callback);
  });

};

exports.deleteStatement = function(registrationId, statementId, callback) {

  //console.log("deleteStatement");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id:  { 'S': registrationId },
      statement_id:     { 'S': statementId }
    },
    TableName: 'xapi-statements'
  }

  dynamodb.deleteItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

}

/////////////
///////////// Helpers for Data Reset
/////////////

deleteStatementList = function(data,callback) {
  if (data==null || data.length == 0) {
    callback();
  } else {
    var item = data.pop();
    var statementId = item['statement_id']['S'];
    var registrationId = item['registration_id']['S'];
    exports.deleteStatement(registrationId, statementId, function() {
      deleteStatementList(data, callback);
    });
  }
}

deleteStateList = function(registrationId, keys, callback) {
  if (keys==null || keys.length == 0) {
    callback(true);
  } else {
    var stateId = keys.pop();
    exports.deleteState({registrationId:registrationId, stateId:stateId}, function() {
      deleteStateList(registrationId, keys, callback);
    });
  }

}

resetStatements = function(callback) {

  var context = {
    registrationId: 'SAMPLE-REGISTRATION-ID'
  };

  exports.findStatements(context,function(data) {
    deleteStatementList(data, callback);
  });

}

resetStates = function(callback) {

  var context = {
    registrationId: 'SAMPLE-REGISTRATION-ID'
  };

  exports.getStateKeys(context,function(data) {
    deleteStateList('SAMPLE-REGISTRATION-ID', data, callback);
  });

}

resetRegistrations = function(callback) {

}

exports.reset = function(callback) {

  // Delete everything associated with the sample
  // registration, and then re-create the sample
  // for the test cases

  resetStatements(function() {
    resetStates(function() {
      exports.deleteRegistration('SAMPLE-REGISTRATION-ID', function() {
        exports.createRegistration('SAMPLE-REGISTRATION-ID', function() {
          callback();
        })
      })
    })
  });
};

<commit_msg>Add some extra logging<commit_after>//
// Dynamo DB Interface
//

var AWS = require('aws-sdk');
AWS.config.update({
  accessKeyId:      process.env.S3_KEY,
  secretAccessKey:  process.env.S3_SECRET,
  region:           process.env.S3_REGION
});

//
// Response Helpers
//

function isEmpty(map) {
   for(var key in map) {
      if (map.hasOwnProperty(key)) {
         return false;
      }
   }
   return true;
}

function responseHelper(err, data, callback) {
  if (err) {
    console.log("** ERROR *********************************************");
    console.log(err, err.stack);
    callback(null);
    throw err;
  } else if (!(data instanceof Array) && isEmpty(data)) {
    callback(null);
  } else {
    callback(data);
  }
}

//
// Public Interface - Registrations
//

exports.allRegistrations = function() {
  // Not Implemented - Debug Only
  return {};
};

// Load Specific Registration
exports.getRegistration = function(registrationId, callback) {

  console.log("getRegistration:" + registrationId);

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id: { 'S': registrationId }
    },
    TableName: 'xapi-registrations'
  }
  console.log(params);

  dynamodb.getItem(params, function(err, data) {
    data = data ? data['Item'] : null;
    responseHelper(err, data, callback);
  });

};

exports.createRegistration = function(registrationId, callback) {

  console.log("createRegistration");

  var data = { registrationId: registrationId };
  var dynamodb = new AWS.DynamoDB();
  var params = {
    Item: {
      registration_id: { 'S': registrationId }
    },
    TableName: 'xapi-registrations'
  }
  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, registrationId, callback);
  });

};

exports.deleteRegistration = function(registrationId, callback) {

  console.log("deleteRegistration");

  var data = { registrationId: registrationId };
  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-registrations',
    Key: {
      registration_id: { 'S': registrationId }
    },
  }
  dynamodb.deleteItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

};

markRegistrationCompleted = function(registrationId, result, callback) {

  var data = { registrationId: registrationId };
  var dynamodb = new AWS.DynamoDB();
  var params = {
    Item: {
      registration_id: { 'S': registrationId },
      status:          { 'S': 'completed' },
      result:          { 'S': JSON.stringify(result) }
    },
    TableName: 'xapi-registrations'
  }
  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, registrationId, callback);
  });

};

//
// Public Interface - States
//

exports.getState = function(context, callback) {

  console.log("getState");

  if (context.stateId==null || context.length==0) {
    throw "asdfasdfasdfsadf";
  }

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id:  { 'S': context.registrationId },
      state_id:         { 'S': context.stateId }
    },
    TableName: 'xapi-states'
  }
  console.log(params);

  dynamodb.getItem(params, function(err, data) {
    data = data ? data['Item'] : null;
    data = data ? data['state_data'] : null;
    data = data ? data['S'] : null;
    responseHelper(err, data, callback);
  });

};

exports.getStateKeys = function(context, callback) {

  console.log("getStateKeys");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-states',
    KeyConditions: {
      registration_id: {
        ComparisonOperator: 'EQ',
        AttributeValueList: [ { 'S': context.registrationId } ]
      }
    },
    AttributesToGet: [ 'state_id' ]
  }
  console.log(params);

  dynamodb.query(params, function(err, data) {
    data = data ? data['Items'] : null;
    var keys = [];
    if (data) {
      for (var i=0; i<data.length; i++) {
        keys[i] = data[i]['state_id'];
        if (keys[i]['S']) {
          keys[i] = keys[i]['S'];
        }
      }
    }
    responseHelper(err, keys, callback);
  });

};

exports.setState = function(context, data, callback) {

  console.log("setState");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Item: {
      registration_id: { 'S': context.registrationId },
      state_id:        { 'S': context.stateId },
      state_data:      { 'S': data }
    },
    TableName: 'xapi-states'
  }
  console.log(params);

  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

};

exports.deleteState = function(context, callback) {

  console.log("deleteState");

  if (context.stateId) {
    var dynamodb = new AWS.DynamoDB();
    var params = {
      Key: {
        registration_id:  { 'S': context.registrationId },
        state_id:         { 'S': context.stateId }
      },
      TableName: 'xapi-states'
    }
    console.log(params);

    dynamodb.deleteItem(params, function(err, data) {
      responseHelper(err, data, callback);
    });

  } else {

    // Missing State Id - Delete all for registration per spec
    exports.getStateKeys(context, function(keys) {
      deleteStateList(context.registrationId, keys, callback);
    });

  }

};

//
// Public Interface - Statements
//

exports.getStatement = function(context, callback) {

  console.log("getStatement");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id:  { 'S': context.registrationId },
      statement_id:     { 'S': context.statementId }
    },
    TableName: 'xapi-statements'
  }
  console.log(params);

  dynamodb.getItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

};

exports.addStatement = function(context, data, callback) {

  console.log("addStatement");

  // Spec says to throw an error if already exists

  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-statements',
    Item: {
      registration_id: { 'S': context.registrationId },
      statement_id:    { 'S': context.statementId },
    }
    /* TODO ,
    Expected: { Exists: false }
    */
  }

  var verbName = data['verb'];
  var result = data['result']

  // Break into components
  for (var key in data) {
    if (data.hasOwnProperty(key)) {
      if (key=='verb') {
        params.Item[key] = { 'S': data[key] };
      } else {
        params.Item[key] = { 'S': JSON.stringify(data[key]) };
      }
    }
  }

  dynamodb.putItem(params, function(err, data) {
    responseHelper(err, data, function(data) {

      // Check for completion?
      if (verbName=='completed') {
        markRegistrationCompleted(context.registrationId,result,function(not_used) {
          callback(data);
        });
      } else {
        callback(data);
      }

    });
  });

};

exports.findStatements = function(context, callback) {

  console.log("findStatements");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    TableName: 'xapi-statements',
    KeyConditions: {
      registration_id: {
        ComparisonOperator: 'EQ',
        AttributeValueList: [ { 'S': context.registrationId } ]
      }
    }
  }
  console.log(params);

  dynamodb.query(params, function(err, data) {
    data = data ? data['Items'] : null;
    responseHelper(err, data, callback);
  });

};

exports.deleteStatement = function(registrationId, statementId, callback) {

  console.log("deleteStatement");

  var dynamodb = new AWS.DynamoDB();
  var params = {
    Key: {
      registration_id:  { 'S': registrationId },
      statement_id:     { 'S': statementId }
    },
    TableName: 'xapi-statements'
  }

  dynamodb.deleteItem(params, function(err, data) {
    responseHelper(err, data, callback);
  });

}

/////////////
///////////// Helpers for Data Reset
/////////////

deleteStatementList = function(data,callback) {
  if (data==null || data.length == 0) {
    callback();
  } else {
    var item = data.pop();
    var statementId = item['statement_id']['S'];
    var registrationId = item['registration_id']['S'];
    exports.deleteStatement(registrationId, statementId, function() {
      deleteStatementList(data, callback);
    });
  }
}

deleteStateList = function(registrationId, keys, callback) {
  if (keys==null || keys.length == 0) {
    callback(true);
  } else {
    var stateId = keys.pop();
    exports.deleteState({registrationId:registrationId, stateId:stateId}, function() {
      deleteStateList(registrationId, keys, callback);
    });
  }

}

resetStatements = function(callback) {

  var context = {
    registrationId: 'SAMPLE-REGISTRATION-ID'
  };

  exports.findStatements(context,function(data) {
    deleteStatementList(data, callback);
  });

}

resetStates = function(callback) {

  var context = {
    registrationId: 'SAMPLE-REGISTRATION-ID'
  };

  exports.getStateKeys(context,function(data) {
    deleteStateList('SAMPLE-REGISTRATION-ID', data, callback);
  });

}

resetRegistrations = function(callback) {

}

exports.reset = function(callback) {

  // Delete everything associated with the sample
  // registration, and then re-create the sample
  // for the test cases

  resetStatements(function() {
    resetStates(function() {
      exports.deleteRegistration('SAMPLE-REGISTRATION-ID', function() {
        exports.createRegistration('SAMPLE-REGISTRATION-ID', function() {
          callback();
        })
      })
    })
  });
};

<|endoftext|>


<commit_before>// PROTO

Object.defineProperties(Element.prototype, {
	"onpress" : {
		set: function(handler) {
			if (MOBILE) {
				var tap;
				this.addEventListener("touchstart", function(){ tap = true; });
				this.addEventListener("touchmove", function(){ tap = false; });
				this.addEventListener("touchend", function(e){ tap && handler.call(this, e); tap = false; });
			} else this.addEventListener("click", handler);
		}
	}
});

// MAIN

var MOBILE 		= 'ontouchstart' in window,
	STANDALONE	= navigator.standalone;

document.documentElement.className += " " + (MOBILE ? (STANDALONE ? 'mobile webapp splash loading' : 'mobile') : 'desktop');

if (MOBILE) {

	addEventListener("load", function(){
		if (STANDALONE) {
			var root = document.documentElement;
			if (RESUMED)
				setTimeout(function(){ root.removeClass("splash loading"); }, 500);
			else {
				root.addClass("load");
				root.removeClass("loading");
				setTimeout(function(){ root.removeClass("splash load"); }, 1000);
			}
		}
	});

	// Prevent inappropriate scrolling on iOS (simulate app)
	document.addEventListener("touchmove", function(e){e.preventDefault();});

}
<commit_msg>Added "loading" class handling<commit_after>// PROTO

Object.defineProperties(Element.prototype, {
	"onpress" : {
		set: function(handler) {
			if (MOBILE) {
				var tap;
				this.addEventListener("touchstart", function(){ tap = true; });
				this.addEventListener("touchmove", function(){ tap = false; });
				this.addEventListener("touchend", function(e){ tap && handler.call(this, e); tap = false; });
			} else this.addEventListener("click", handler);
		}
	}
});

// MAIN

var MOBILE 		= 'ontouchstart' in window,
	STANDALONE	= navigator.standalone;

document.documentElement.className += 'loading ' + (MOBILE ? 'mobile ' + (STANDALONE ? 'webapp splash' : '') : 'desktop');

if (MOBILE) {

	addEventListener("load", function(){
		if (STANDALONE) {
			var root = document.documentElement;
			if (RESUMED)
				setTimeout(function(){ root.removeClass("splash"); }, 500);
			else {
				root.addClass("load");
				root.removeClass("loading");
				setTimeout(function(){ root.removeClass("splash load"); }, 1000);
			}
		}
	});

	// Prevent inappropriate scrolling on iOS (simulate app)
	document.addEventListener("touchmove", function(e){e.preventDefault();});

}

addEventListener("load", function() {
	document.documentElement.removeClass("loading");
});
<|endoftext|>


<commit_before>dojo.provide("dojox.data.util.JsonQuery");
// this is a mixin to convert object attribute queries to
// JSONQuery/JSONPath syntax to be sent to the server.
dojo.declare("dojox.data.util.JsonQuery", null, {
	useFullIdInQueries: false,
	_toJsonQuery: function(args, jsonQueryPagination){
		var first = true;
		var self = this;
		function buildQuery(path, query){
			var isDataItem = query.__id;
			if(isDataItem){
				// it is a reference to a persisted object, need to make it a query by id
				var newQuery = {};
				newQuery[self.idAttribute] = self.useFullIdInQueries ? query.__id : query[self.idAttribute];
				query = newQuery;
			}
			for(var i in query){
				// iterate through each property, adding them to the overall query
				var value = query[i];
				var newPath = path + (/^[a-zA-Z_][\w_]*$/.test(i) ? '.' + i : '[' + dojo._escapeString(i) + ']');
				if(value && typeof value == "object"){
					buildQuery(newPath, value);
				}else if(value!="*"){ // full wildcards can be ommitted
					jsonQuery += (first ? "" : "&") + newPath +
						((!isDataItem && typeof value == "string" && args.queryOptions && args.queryOptions.ignoreCase) ? "~" : "=") +
						 (self.simplifiedQuery ? encodeURIComponent(value) : dojo.toJson(value));
					first = false;
				}
			}
		}
		// performs conversion of Dojo Data query objects and sort arrays to JSONQuery strings
		if(args.query && typeof args.query == "object"){
			// convert Dojo Data query objects to JSONQuery
			var jsonQuery = "[?(";
			buildQuery("@", args.query);
			if(!first){
				// use ' instead of " for quoting in JSONQuery, and end with ]
				jsonQuery += ")]";
			}else{
				jsonQuery = "";
			}
			args.queryStr = jsonQuery.replace(/\\"|"/g,function(t){return t == '"' ? "'" : t;});
		}else if(!args.query || args.query == '*'){
			args.query = "";
		}

		var sort = args.sort;
		if(sort){
			// if we have a sort order, add that to the JSONQuery expression
			args.queryStr = args.queryStr || (typeof args.query == 'string' ? args.query : "");
			first = true;
			for(i = 0; i < sort.length; i++){
				args.queryStr += (first ? '[' : ',') + (sort[i].descending ? '\\' : '/') + "@[" + dojo._escapeString(sort[i].attribute) + "]";
				first = false;
			}
		}
		// this is optional because with client side paging JSONQuery doesn't yield the total count
		if(jsonQueryPagination && (args.start || args.count)){
			// pagination
			args.queryStr = (args.queryStr || (typeof args.query == 'string' ? args.query : "")) +
				'[' + (args.start || '') + ':' + (args.count ? (args.start || 0) + args.count : '') + ']';
		}
		if(typeof args.queryStr == 'string'){
			args.queryStr = args.queryStr.replace(/\\"|"/g,function(t){return t == '"' ? "'" : t;});
			return args.queryStr;
		}
		return args.query;
	},
	jsonQueryPagination: true,
	fetch: function(args){
		this._toJsonQuery(args, this.jsonQueryPagination);
		return this.inherited(arguments);
	},
	isUpdateable: function(){
		return true;
	},
	matchesQuery: function(item,request){
		request._jsonQuery = request._jsonQuery || dojox.json.query(this._toJsonQuery(request));
		return request._jsonQuery([item]).length;
	},
	clientSideFetch: function(/*Object*/ request,/*Array*/ baseResults){
		request._jsonQuery = request._jsonQuery || dojox.json.query(this._toJsonQuery(request));
		// we use client side paging function here instead of JSON Query because we must also determine the total count
		return this.clientSidePaging(request, request._jsonQuery(baseResults));
	},
	querySuperSet: function(argsSuper,argsSub){
		if(!argsSuper.query){
			return argsSub.query;
		}
		return this.inherited(arguments);
	}

});
<commit_msg>Closing bracket, fixes #11565<commit_after>dojo.provide("dojox.data.util.JsonQuery");
// this is a mixin to convert object attribute queries to
// JSONQuery/JSONPath syntax to be sent to the server.
dojo.declare("dojox.data.util.JsonQuery", null, {
	useFullIdInQueries: false,
	_toJsonQuery: function(args, jsonQueryPagination){
		var first = true;
		var self = this;
		function buildQuery(path, query){
			var isDataItem = query.__id;
			if(isDataItem){
				// it is a reference to a persisted object, need to make it a query by id
				var newQuery = {};
				newQuery[self.idAttribute] = self.useFullIdInQueries ? query.__id : query[self.idAttribute];
				query = newQuery;
			}
			for(var i in query){
				// iterate through each property, adding them to the overall query
				var value = query[i];
				var newPath = path + (/^[a-zA-Z_][\w_]*$/.test(i) ? '.' + i : '[' + dojo._escapeString(i) + ']');
				if(value && typeof value == "object"){
					buildQuery(newPath, value);
				}else if(value!="*"){ // full wildcards can be ommitted
					jsonQuery += (first ? "" : "&") + newPath +
						((!isDataItem && typeof value == "string" && args.queryOptions && args.queryOptions.ignoreCase) ? "~" : "=") +
						 (self.simplifiedQuery ? encodeURIComponent(value) : dojo.toJson(value));
					first = false;
				}
			}
		}
		// performs conversion of Dojo Data query objects and sort arrays to JSONQuery strings
		if(args.query && typeof args.query == "object"){
			// convert Dojo Data query objects to JSONQuery
			var jsonQuery = "[?(";
			buildQuery("@", args.query);
			if(!first){
				// use ' instead of " for quoting in JSONQuery, and end with ]
				jsonQuery += ")]";
			}else{
				jsonQuery = "";
			}
			args.queryStr = jsonQuery.replace(/\\"|"/g,function(t){return t == '"' ? "'" : t;});
		}else if(!args.query || args.query == '*'){
			args.query = "";
		}

		var sort = args.sort;
		if(sort){
			// if we have a sort order, add that to the JSONQuery expression
			args.queryStr = args.queryStr || (typeof args.query == 'string' ? args.query : "");
			first = true;
			for(i = 0; i < sort.length; i++){
				args.queryStr += (first ? '[' : ',') + (sort[i].descending ? '\\' : '/') + "@[" + dojo._escapeString(sort[i].attribute) + "]";
				first = false;
			}
			args.queryStr += ']';
		}
		// this is optional because with client side paging JSONQuery doesn't yield the total count
		if(jsonQueryPagination && (args.start || args.count)){
			// pagination
			args.queryStr = (args.queryStr || (typeof args.query == 'string' ? args.query : "")) +
				'[' + (args.start || '') + ':' + (args.count ? (args.start || 0) + args.count : '') + ']';
		}
		if(typeof args.queryStr == 'string'){
			args.queryStr = args.queryStr.replace(/\\"|"/g,function(t){return t == '"' ? "'" : t;});
			return args.queryStr;
		}
		return args.query;
	},
	jsonQueryPagination: true,
	fetch: function(args){
		this._toJsonQuery(args, this.jsonQueryPagination);
		return this.inherited(arguments);
	},
	isUpdateable: function(){
		return true;
	},
	matchesQuery: function(item,request){
		request._jsonQuery = request._jsonQuery || dojox.json.query(this._toJsonQuery(request));
		return request._jsonQuery([item]).length;
	},
	clientSideFetch: function(/*Object*/ request,/*Array*/ baseResults){
		request._jsonQuery = request._jsonQuery || dojox.json.query(this._toJsonQuery(request));
		// we use client side paging function here instead of JSON Query because we must also determine the total count
		return this.clientSidePaging(request, request._jsonQuery(baseResults));
	},
	querySuperSet: function(argsSuper,argsSub){
		if(!argsSuper.query){
			return argsSub.query;
		}
		return this.inherited(arguments);
	}

});
<|endoftext|>


<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

it('adds 1 + 2 to equal 3 in CoffeeScript', () => {
  const sum = require('../sum.ts');
  expect(sum(1, 2)).toBe(3);
});

it('adds 1 + 2 to equal 3 in JavaScript', () => {
  const sum = require('../sum.js');
  expect(sum(1, 2)).toBe(3);
});
<commit_msg>Correct typo in TS example (#2018)<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

it('adds 1 + 2 to equal 3 in Typescript', () => {
  const sum = require('../sum.ts');
  expect(sum(1, 2)).toBe(3);
});

it('adds 1 + 2 to equal 3 in JavaScript', () => {
  const sum = require('../sum.js');
  expect(sum(1, 2)).toBe(3);
});
<|endoftext|>