whole_func_string: function appendPropertyTRs (parent, plist, inverse, predicateFilter) {
        // UI.log.info('@appendPropertyTRs, 'this' is %s, dom is %s, '+ // Gives 'can't access dead object'
        //                   'thisOutline.document is %s', this, dom.location, thisOutline.document.location);
        // UI.log.info('@appendPropertyTRs, dom is now ' + this.document.location);
        // UI.log.info('@appendPropertyTRs, dom is now ' + thisOutline.document.location);
      UI.log.debug('Property list length = ' + plist.length)
      if (plist.length === 0) return ''
      var sel, j, k
      if (inverse) {
        sel = function (x) {
          return x.subject
        }
        plist = plist.sort(UI.utils.RDFComparePredicateSubject)
      } else {
        sel = function (x) {
          return x.object
        }
        plist = plist.sort(UI.utils.RDFComparePredicateObject)
      }
  
      var max = plist.length
      for (j = 0; j < max; j++) { // squishing together equivalent properties I think
        var s = plist[j]
            //      if (s.object == parentSubject) continue; // that we knew
  
          // Avoid predicates from other panes
        if (predicateFilter && !predicateFilter(s.predicate, inverse)) continue
  
        var tr = propertyTR(dom, s, inverse)
        parent.appendChild(tr)
        var predicateTD = tr.firstChild // we need to kludge the rowspan later
  
        var defaultpropview = views.defaults[s.predicate.uri]
  
        //   LANGUAGE PREFERENCES WAS AVAILABLE WITH FF EXTENSION - get from elsewhere?
  
        var dups = 0 // How many rows have the same predicate, -1?
        var langTagged = 0 // how many objects have language tags?
        var myLang = 0 // Is there one I like?
  
        for (k = 0;
            (k + j < max) && (plist[j + k].predicate.sameTerm(s.predicate)); k++) {
          if (k > 0 && (sel(plist[j + k]).sameTerm(sel(plist[j + k - 1])))) dups++
          if (sel(plist[j + k]).lang && outline.labeller.LanguagePreference) {
            langTagged += 1
            if (sel(plist[j + k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) myLang++
          }
        }
  
          /* Display only the one in the preferred language
            ONLY in the case (currently) when all the values are tagged.
            Then we treat them as alternatives. */
  
        if (myLang > 0 && langTagged === dups + 1) {
          for (let k = j; k <= j + dups; k++) {
            if (outline.labeller.LanguagePreference && sel(plist[k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) {
              tr.appendChild(thisOutline.outlineObjectTD(sel(plist[k]), defaultpropview, undefined, s))
              break
            }
          }
          j += dups // extra push
          continue
        }
  
        tr.appendChild(thisOutline.outlineObjectTD(sel(s), defaultpropview, undefined, s))
  
          /* Note: showNobj shows between n to 2n objects.
           * This is to prevent the case where you have a long list of objects
           * shown, and dangling at the end is '1 more' (which is easily ignored)
           * Therefore more objects are shown than hidden.
           */
  
        tr.showNobj = function (n) {
          var predDups = k - dups
          var show = ((2 * n) < predDups) ? n : predDups
          var showLaterArray = []
          if (predDups !== 1) {
            predicateTD.setAttribute('rowspan', (show === predDups) ? predDups : n + 1)
            var l
            if ((show < predDups) && (show === 1)) { // what case is this...
              predicateTD.setAttribute('rowspan', 2)
            }
            var displayed = 0 // The number of cells generated-1,
                // all duplicate thing removed
            for (l = 1; l < k; l++) {
                  // This detects the same things
              if (!kb.canon(sel(plist[j + l])).sameTerm(kb.canon(sel(plist[j + l - 1])))) {
                displayed++
                s = plist[j + l]
                defaultpropview = views.defaults[s.predicate.uri]
                var trObj = dom.createElement('tr')
                trObj.style.colspan = '1'
                trObj.appendChild(thisOutline.outlineObjectTD(
                      sel(plist[j + l]), defaultpropview, undefined, s))
                trObj.AJAR_statement = s
                trObj.AJAR_inverse = inverse
                parent.appendChild(trObj)
                if (displayed >= show) {
                  trObj.style.display = 'none'
                  showLaterArray.push(trObj)
                }
              } else {
                    // ToDo: show all the data sources of this statement
                UI.log.info('there are duplicates here: %s', plist[j + l - 1])
              }
            }
                // @@a quick fix on the messing problem.
            if (show === predDups) { predicateTD.setAttribute('rowspan', displayed + 1) }
          } // end of if (predDups!==1)
  
          if (show < predDups) { // Add the x more <TR> here
            var moreTR = dom.createElement('tr')
            var moreTD = moreTR.appendChild(dom.createElement('td'))
            moreTD.setAttribute('style', 'margin: 0.2em; border: none; padding: 0; vertical-align: top;')
            moreTD.setAttribute('notSelectable', 'false')
            if (predDups > n) { // what is this for??
              var small = dom.createElement('a')
              moreTD.appendChild(small)
  
              var predToggle = (function (f) {
                return f(predicateTD, k, dups, n)
              })(function (predicateTD, k, dups, n) {
                return function (display) {
                  small.innerHTML = ''
                  if (display === 'none') {
                    small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-more-trans.png', 'more', 'See all', dom))
                    small.appendChild(dom.createTextNode((predDups - n) + ' more...'))
                    predicateTD.setAttribute('rowspan', n + 1)
                  } else {
                    small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-shrink.png', '(less)', undefined, dom))
                    predicateTD.setAttribute('rowspan', predDups + 1)
                  }
                  for (var i = 0; i < showLaterArray.length; i++) {
                    var trObj = showLaterArray[i]
                    trObj.style.display = display
                  }
                }
              }) // ???
              var current = 'none'
              var toggleObj = function (event) {
                predToggle(current)
                current = (current === 'none') ? '' : 'none'
                if (event) event.stopPropagation()
                return false // what is this for?
              }
              toggleObj()
              small.addEventListener('click', toggleObj, false)
            } // if(predDups>n)
            parent.appendChild(moreTR)
          } // if
        } // tr.showNobj
  
        tr.showAllobj = function () {
          tr.showNobj(k - dups)
        }
  
        tr.showNobj(10)
  
        j += k - 1 // extra push
      }
    }
func_code_string: function appendPropertyTRs (parent, plist, inverse, predicateFilter) {
        // UI.log.info('@appendPropertyTRs, 'this' is %s, dom is %s, '+ // Gives 'can't access dead object'
        //                   'thisOutline.document is %s', this, dom.location, thisOutline.document.location);
        // UI.log.info('@appendPropertyTRs, dom is now ' + this.document.location);
        // UI.log.info('@appendPropertyTRs, dom is now ' + thisOutline.document.location);
      UI.log.debug('Property list length = ' + plist.length)
      if (plist.length === 0) return ''
      var sel, j, k
      if (inverse) {
        sel = function (x) {
          return x.subject
        }
        plist = plist.sort(UI.utils.RDFComparePredicateSubject)
      } else {
        sel = function (x) {
          return x.object
        }
        plist = plist.sort(UI.utils.RDFComparePredicateObject)
      }
  
      var max = plist.length
      for (j = 0; j < max; j++) { // squishing together equivalent properties I think
        var s = plist[j]
            //      if (s.object == parentSubject) continue; // that we knew
  
          // Avoid predicates from other panes
        if (predicateFilter && !predicateFilter(s.predicate, inverse)) continue
  
        var tr = propertyTR(dom, s, inverse)
        parent.appendChild(tr)
        var predicateTD = tr.firstChild // we need to kludge the rowspan later
  
        var defaultpropview = views.defaults[s.predicate.uri]
  
        //   LANGUAGE PREFERENCES WAS AVAILABLE WITH FF EXTENSION - get from elsewhere?
  
        var dups = 0 // How many rows have the same predicate, -1?
        var langTagged = 0 // how many objects have language tags?
        var myLang = 0 // Is there one I like?
  
        for (k = 0;
            (k + j < max) && (plist[j + k].predicate.sameTerm(s.predicate)); k++) {
          if (k > 0 && (sel(plist[j + k]).sameTerm(sel(plist[j + k - 1])))) dups++
          if (sel(plist[j + k]).lang && outline.labeller.LanguagePreference) {
            langTagged += 1
            if (sel(plist[j + k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) myLang++
          }
        }
  
          /* Display only the one in the preferred language
            ONLY in the case (currently) when all the values are tagged.
            Then we treat them as alternatives. */
  
        if (myLang > 0 && langTagged === dups + 1) {
          for (let k = j; k <= j + dups; k++) {
            if (outline.labeller.LanguagePreference && sel(plist[k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) {
              tr.appendChild(thisOutline.outlineObjectTD(sel(plist[k]), defaultpropview, undefined, s))
              break
            }
          }
          j += dups // extra push
          continue
        }
  
        tr.appendChild(thisOutline.outlineObjectTD(sel(s), defaultpropview, undefined, s))
  
          /* Note: showNobj shows between n to 2n objects.
           * This is to prevent the case where you have a long list of objects
           * shown, and dangling at the end is '1 more' (which is easily ignored)
           * Therefore more objects are shown than hidden.
           */
  
        tr.showNobj = function (n) {
          var predDups = k - dups
          var show = ((2 * n) < predDups) ? n : predDups
          var showLaterArray = []
          if (predDups !== 1) {
            predicateTD.setAttribute('rowspan', (show === predDups) ? predDups : n + 1)
            var l
            if ((show < predDups) && (show === 1)) { // what case is this...
              predicateTD.setAttribute('rowspan', 2)
            }
            var displayed = 0 // The number of cells generated-1,
                // all duplicate thing removed
            for (l = 1; l < k; l++) {
                  // This detects the same things
              if (!kb.canon(sel(plist[j + l])).sameTerm(kb.canon(sel(plist[j + l - 1])))) {
                displayed++
                s = plist[j + l]
                defaultpropview = views.defaults[s.predicate.uri]
                var trObj = dom.createElement('tr')
                trObj.style.colspan = '1'
                trObj.appendChild(thisOutline.outlineObjectTD(
                      sel(plist[j + l]), defaultpropview, undefined, s))
                trObj.AJAR_statement = s
                trObj.AJAR_inverse = inverse
                parent.appendChild(trObj)
                if (displayed >= show) {
                  trObj.style.display = 'none'
                  showLaterArray.push(trObj)
                }
              } else {
                    // ToDo: show all the data sources of this statement
                UI.log.info('there are duplicates here: %s', plist[j + l - 1])
              }
            }
                // @@a quick fix on the messing problem.
            if (show === predDups) { predicateTD.setAttribute('rowspan', displayed + 1) }
          } // end of if (predDups!==1)
  
          if (show < predDups) { // Add the x more <TR> here
            var moreTR = dom.createElement('tr')
            var moreTD = moreTR.appendChild(dom.createElement('td'))
            moreTD.setAttribute('style', 'margin: 0.2em; border: none; padding: 0; vertical-align: top;')
            moreTD.setAttribute('notSelectable', 'false')
            if (predDups > n) { // what is this for??
              var small = dom.createElement('a')
              moreTD.appendChild(small)
  
              var predToggle = (function (f) {
                return f(predicateTD, k, dups, n)
              })(function (predicateTD, k, dups, n) {
                return function (display) {
                  small.innerHTML = ''
                  if (display === 'none') {
                    small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-more-trans.png', 'more', 'See all', dom))
                    small.appendChild(dom.createTextNode((predDups - n) + ' more...'))
                    predicateTD.setAttribute('rowspan', n + 1)
                  } else {
                    small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-shrink.png', '(less)', undefined, dom))
                    predicateTD.setAttribute('rowspan', predDups + 1)
                  }
                  for (var i = 0; i < showLaterArray.length; i++) {
                    var trObj = showLaterArray[i]
                    trObj.style.display = display
                  }
                }
              }) // ???
              var current = 'none'
              var toggleObj = function (event) {
                predToggle(current)
                current = (current === 'none') ? '' : 'none'
                if (event) event.stopPropagation()
                return false // what is this for?
              }
              toggleObj()
              small.addEventListener('click', toggleObj, false)
            } // if(predDups>n)
            parent.appendChild(moreTR)
          } // if
        } // tr.showNobj
  
        tr.showAllobj = function () {
          tr.showNobj(k - dups)
        }
  
        tr.showNobj(10)
  
        j += k - 1 // extra push
      }
    }
func_documentation_string: / ////////// Property list