[ignore] import module should be loaded base on controller location

svn path=/trunk/eXist/; revision=11170

xquery version "1.0";

import module namespace app = "http://exist-db.org/application" at "application.xqm";

let $baseURL : = concat($exist:prefix, $exist:root, $exist:controller, '/')
return
if ($exist:path eq 'login.xql') then
	<ignore xmlns="http://exist.sourceforge.net/NS/exist">
		<cache-control cache="yes"/>
	</ignore>
else if (starts-with($exist:path, '/css/')) then
	<ignore xmlns="http://exist.sourceforge.net/NS/exist">
		<cache-control cache="yes"/>
	</ignore>
else if (not (xmldb:is-authenticated())) then
	if ($exist:path eq '') then
		<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
			<redirect url="{baseURL}"/>
		</dispatch>
	else
		<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
			<forward url="{concat($baseURL, "login.xql")}"/>
		</dispatch>

else if ($exist:path eq '/') then
	<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
		<forward url="index.xql"/>
	</dispatch>
else
	let $app := $exist:resource
	return
	if (ends-with($app, ".xql")) then
		<ignore xmlns="http://exist.sourceforge.net/NS/exist">
			<cache-control cache="yes"/>
		</ignore>
	else if (not($app eq "")) then
		<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
			<redirect url="{concat($baseURL, app:path($app))}"/>
		</dispatch>
	else
		(: everything else is passed through :)
		<ignore xmlns="http://exist.sourceforge.net/NS/exist">
			<cache-control cache="yes"/>
		</ignore>

xquery version "1.0";

import module namespace app = "http://exist-db.org/application" at "/administration/application.xqm";

let $baseURL : = concat($exist:prefix, $exist:root, $exist:controller, '/')
return
if ($exist:path eq 'login.xql') then
	<ignore xmlns="http://exist.sourceforge.net/NS/exist">
		<cache-control cache="yes"/>
	</ignore>
else if (starts-with($exist:path, '/css/')) then
	<ignore xmlns="http://exist.sourceforge.net/NS/exist">
		<cache-control cache="yes"/>
	</ignore>
else if (not (xmldb:is-authenticated())) then
	if ($exist:path eq '') then
		<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
			<redirect url="{baseURL}"/>
		</dispatch>
	else
		<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
			<forward url="{concat($baseURL, "login.xql")}"/>
		</dispatch>

else if ($exist:path eq '/') then
	<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
		<forward url="index.xql"/>
	</dispatch>
else
	let $app := $exist:resource
	return
	if (ends-with($app, ".xql")) then
		<ignore xmlns="http://exist.sourceforge.net/NS/exist">
			<cache-control cache="yes"/>
		</ignore>
	else if (not($app eq "")) then
		<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
			<redirect url="{concat($baseURL, app:path($app))}"/>
		</dispatch>
	else
		(: everything else is passed through :)
		<ignore xmlns="http://exist.sourceforge.net/NS/exist">
			<cache-control cache="yes"/>
		</ignore>


Preparing for positioning

Preparing for positioning

xquery version "3.1";

(: http://limpet.net/mbrubeck/2014/09/08/toy-layout-engine-5-boxes.html :)
(: https://github.com/tel/frame :)
(: https://github.com/tel/frame/blob/master/src/frame/fstate.clj :)
(: http://www.ibm.com/developerworks/library/j-treevisit/ :)
(: https://github.com/akhudek/zip-visit :)

module namespace ex = 'http://xokomola.com/xquery/origami/examples';

import module namespace o = 'http://xokomola.com/xquery/origami'
    at '../../origami/origami.xqm';

declare function ex:report($node)
{
    let $report := trace(o:tag($node), 'TAG: ')
    return
        $node
};

declare function ex:advise-dimensions($node, $width, $height)
{
    array {
        o:tag($node),
        map:merge((
            map {
                'width': $width,
                'height': $height
            },
            o:attrs($node)
        )),
        o:children($node)
    }
};

declare function ex:collect-attribute($nodes, $attribute)
{
    fold-left(
        $nodes,
        [],
        function($result,$item) {
            array:append($result,o:attrs($item)($attribute))
        }
    )
};

declare function ex:count-attribute($nodes, $attribute)
as xs:integer
{
    sum(
        for $node in $nodes
        where o:attrs($node)($attribute)
        return 1
    )
};

declare function ex:advise($a,$b)
{
    let $b :=
        if ($b instance of array(*)) then
            $b
        else
            array { for $i in 1 to array:size($a) return $b }
    return
        array:for-each-pair($a,$b, function($a,$b) { ($a,$b)[1] })
};

declare function ex:layout-node-children($node)
{
    let $tag := o:tag($node)
    let $attrs := o:attrs($node)
    let $children := o:children($node)
    let $child-count := count($children)
    let $width := $attrs?width
    let $height := $attrs?height
    return
        array {
            $tag,
            $attrs,
            if ($tag = 'hbox') then
                let $child-widths := ex:collect-attribute($children,'width')
                let $advised-width :=
                    ($width - sum($child-widths))
                    div ($child-count - ex:count-attribute($children,'width'))
                let $advice := ex:advise($child-widths, $advised-width)
                for $child at $pos in $children
                return
                    $child => o:set-attr(map { 'height': $height, 'width': $advice($pos) })
            else
                let $child-heights := ex:collect-attribute($children,'height')
                let $advised-height :=
                    ($height - sum($child-heights))
                    div ($child-count - ex:count-attribute($children,'height'))
                let $advice := ex:advise($child-heights, $advised-height)
                for $child at $pos in $children
                return
                    $child => o:set-attr(map { 'width': $width, 'height': $advice($pos) })
        }
};

declare function ex:layout-node($node)
{
    let $tag := o:tag($node)
    let $attrs := o:attrs($node)
    let $children := o:children($node)
    let $height := 40
    let $width := 100
    return
        if (count($children) = 0) then
            ex:advise-dimensions($node,
                $width,
                $height
            )
        else if ($tag = 'hbox') then
            ex:advise-dimensions($node,
                sum(o:map($children, function($n) { o:attrs($n)?width })),
                max(o:map($children, function($n) { o:attrs($n)?height }))
            )
        else
            ex:advise-dimensions($node,
                max(o:map($children, function($n) { o:attrs($n)?width })),
                sum(o:map($children, function($n) { o:attrs($n)?height }))
            )
};
declare function ex:layout-top-down($mu)
{
    o:prewalk($mu, ex:layout-node-children#1)
};

declare function ex:layout-bottom-up($mu)
{
    o:postwalk($mu, ex:layout-node#1)
};

declare function ex:render-svg-node($node)
{
    array {
        'rect',
        map { 'x': 0, 'y': 0,
            'width': o:attrs($node)?width,
            'height': o:attrs($node)?height,
            'fill': ex:random-color(),
            'fill-opacity': 0.5,
            'stroke-width': 1,
            'stroke': 'black',
            'stroke-opacity': 1
        }
    },
    o:children($node)
};

declare function ex:random-color()
{
    concat(
        'rgb(',
        random:integer(255), ',',
        random:integer(255), ',',
        random:integer(255),
        ')'
    )
};

declare function ex:svg-builder()
{
    o:default-ns-builder(
        'http://www.w3.org/2000/svg'
    )
};

declare function ex:svg($mu)
{
    ['svg', o:postwalk($mu, ex:render-svg-node#1)]
};

xquery version "3.1";

(: http://limpet.net/mbrubeck/2014/09/08/toy-layout-engine-5-boxes.html :)
(: https://github.com/tel/frame :)
(: https://github.com/tel/frame/blob/master/src/frame/fstate.clj :)
(: http://www.ibm.com/developerworks/library/j-treevisit/ :)
(: https://github.com/akhudek/zip-visit :)

module namespace ex = 'http://xokomola.com/xquery/origami/examples';

import module namespace o = 'http://xokomola.com/xquery/origami'
    at '../../origami/origami.xqm';

declare function ex:report($node)
{
    let $report := trace(o:tag($node), 'TAG: ')
    return
        $node
};

declare function ex:advise-dimensions($node, $width, $height)
{
    array {
        o:tag($node),
        map:merge((
            map {
                'width': $width,
                'height': $height
            },
            o:attrs($node)
        )),
        o:children($node)
    }
};

declare function ex:collect-attribute($nodes, $attribute)
{
    fold-left(
        $nodes,
        [],
        function($result,$item) {
            array:append($result,o:attrs($item)($attribute))
        }
    )
};

declare function ex:count-attribute($nodes, $attribute)
as xs:integer
{
    sum(
        for $node in $nodes
        where o:attrs($node)($attribute)
        return 1
    )
};

declare function ex:layout-node-children($node)
{
    let $tag := o:tag($node)
    let $attrs := o:attrs($node)
    let $children := o:children($node)
    let $child-count := count($children)
    let $width := $attrs?width
    let $height := $attrs?height
    return
        array {
            $tag,
            $attrs,
            if ($tag = 'hbox') then
                let $child-widths := ex:collect-attribute($children,'width')
                let $advised-width :=
                    ($width - sum($child-widths))
                    div ($child-count - ex:count-attribute($children,'width'))
                for $child in $children
                return
                    ex:advise-dimensions($child, $advised-width, $height)
            else
                let $child-heights := ex:collect-attribute($children,'height')
                let $advised-height :=
                    ($height - sum($child-heights))
                    div ($child-count - ex:count-attribute($children,'height'))
                for $child in $children
                return
                    ex:advise-dimensions($child, $width, $advised-height)
        }
};

declare function ex:layout-node($node)
{
    let $tag := o:tag($node)
    let $attrs := o:attrs($node)
    let $children := o:children($node)
    let $height := 40
    let $width := 100
    return
        if (count($children) = 0) then
            ex:advise-dimensions($node,
                $width,
                $height
            )
        else if ($tag = 'hbox') then
            ex:advise-dimensions($node,
                sum(o:map($children, function($n) { o:attrs($n)?width })),
                max(o:map($children, function($n) { o:attrs($n)?height }))
            )
        else
            ex:advise-dimensions($node,
                max(o:map($children, function($n) { o:attrs($n)?width })),
                sum(o:map($children, function($n) { o:attrs($n)?height }))
            )
};
declare function ex:layout-top-down($mu)
{
    o:prewalk($mu, ex:layout-node-children#1)
};

declare function ex:layout-bottom-up($mu)
{
    o:postwalk($mu, ex:layout-node#1)
};

declare function ex:render-svg-node($node)
{
    array {
        'rect',
        map { 'x': 0, 'y': 0,
            'width': o:attrs($node)?width,
            'height': o:attrs($node)?height,
            'fill': ex:random-color(),
            'fill-opacity': 0.5,
            'stroke-width': 1,
            'stroke': 'black',
            'stroke-opacity': 1
        }
    },
    o:children($node)
};

declare function ex:random-color()
{
    concat(
        'rgb(',
        random:integer(255), ',',
        random:integer(255), ',',
        random:integer(255),
        ')'
    )
};

declare function ex:svg-builder()
{
    o:default-ns-builder(
        'http://www.w3.org/2000/svg'
    )
};

declare function ex:svg($mu)
{
    ['svg', o:postwalk($mu, ex:render-svg-node#1)]
};


added missing $ in base query for services

(:~
: This is a module contatining the required stored queries for Care Services Discovery
: @version 1.0
: @see https://github.com/his-interop/openinfoman @see http://ihe.net
:
:)
module namespace csd_bsq = "https://github.com/his-interop/openinfoman/csd_bsq";

import module namespace csd = "urn:ihe:iti:csd:2013" at "csd_base_library.xqm";

declare default element  namespace   "urn:ihe:iti:csd:2013";

declare variable $csd_bsq:stored_functions :=
(
   <function uuid='4e8bbeb9-f5f5-11e2-b778-0800200c9a66'
   	     method='csd_bsq:provider_search'
 	     content-type='text/xml; charset=utf-8'
	     />,
   <function uuid='dc6aedf0-f609-11e2-b778-0800200c9a66'
   	     method='csd_bsq:organization_search'
 	     content-type='text/xml; charset=utf-8'
	     />,
   <function uuid='e3d8ecd0-f605-11e2-b778-0800200c9a66'
   	     method='csd_bsq:service_search'
 	     content-type='text/xml; charset=utf-8'
	     />,
   <function uuid='c7640530-f600-11e2-b778-0800200c9a66'
   	     method='csd_bsq:facility_search'
 	     content-type='text/xml; charset=utf-8'
	     />
);

declare function csd_bsq:provider_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory>
    {

      let $provs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/providerDirectory/*,$requestParams/id)
      else $doc/CSD/providerDirectory/*

      let $provs1 := if(exists($requestParams/otherID))
	then csd:filter_by_other_id($provs0,$requestParams/otherID)
      else $provs0

      let $provs2 := if(exists($requestParams/commonName))
	then csd:filter_by_common_name($provs1,$requestParams/commonName)
      else $provs1

      let $provs3 := if (exists($requestParams/codedType))
	then csd:filter_by_coded_type($provs2,$requestParams/codedType)
      else $provs2

      let $provs4 := if (exists($requestParams/address/addressLine))
	then csd:filter_by_address($provs3, $requestParams/address/addressLine)
      else $provs3

      let $provs5 :=  if (exists($requestParams/record))
	then csd:filter_by_record($provs4,$requestParams/record)
      else  $provs4

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items($provs5,$requestParams/start,$requestParams/max)
	else csd:limit_items($provs5,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items($provs5,<start/>,$requestParams/max)
	else $provs5

    }
  </providerDirectory>
</CSD>

};

declare function csd_bsq:organization_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory>
    {
      let $orgs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/organizationDirectory/*,$requestParams/id)
	else $doc/CSD/organizationDirectory/*

      let $orgs1 := if (exists($requestParams/primaryName))
	then csd:filter_by_primary_name($orgs0,$requestParams/primaryName)
      else $orgs0

      let $orgs2 := if(exists($requestParams/name))
	then csd:filter_by_name($orgs1,$requestParams/name)
      else $orgs1

      let $orgs3 := if(exists($requestParams/codedType))
	then csd:filter_by_coded_type($orgs2,$requestParams/codedType)
	else $orgs2

      let $orgs4 :=if (exists($requestParams/address/addressLine))
	then csd:filter_by_address($orgs3, $requestParams/address/addressLine)
	else $orgs3

      let $orgs5 := if (exists($requestParams/record))
	then csd:filter_by_record($orgs4,$requestParams/record)
      else $orgs4

      let $orgs6 := if (exists($requestParams/otherID))
	then csd:filter_by_other_id($orgs5,$requestParams/otherID)
      else $orgs5

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items($orgs6,$requestParams/start,$requestParams/max)
	else csd:limit_items($orgs6,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items($orgs6,<start/>,$requestParams/max)
	else $orgs6

    }
  </organizationDirectory>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory/>
</CSD>
};

declare function csd_bsq:facility_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory>
    {
      let $facs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/facilityDirectory/*,$requestParams/id)
      else $doc/CSD/facilityDirectory/*

      let $facs1 := if (exists($requestParams/primaryName))
	then csd:filter_by_primary_name($facs0,$requestParams/primaryName)
      else $facs0

      let $facs2 := if (exists($requestParams/name))
	then csd:filter_by_name($facs1,$requestParams/name)
      else $facs1

      let $facs3 := if(exists($requestParams/codedType))
	then csd:filter_by_coded_type($facs2,$requestParams/codedType)
      else $facs2

      let $facs4 := if(exists($requestParams/address/addressLine))
	then csd:filter_by_address($facs3, $requestParams/address/addressLine)
      else $facs3

      let $facs5 := if (exists($requestParams/record))
	then csd:filter_by_record($facs4,$requestParams/record)
      else $facs4

      let $facs6 := if(exists($requestParams/otherID))
	then csd:filter_by_other_id($facs5,$requestParams/otherID)
      else $facs5

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items($facs6,$requestParams/start,$requestParams/max)
	else csd:limit_items($facs6,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items($facs6,<start/>,$requestParams/max)
	else $facs6

    }
  </facilityDirectory>
  <providerDirectory/>
</CSD>
};

declare function csd_bsq:service_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory>
    {
      let $svcs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/serviceDirectory/*,$requestParams/id)
      else $doc/CSD/serviceDirectory/*

      let $svcs1 := if(exists($requestParams/codedType))
	then csd:filter_by_coded_type($svcs0,$requestParams/codedType)
      else $svcs0

      let $svcs2 :=  if (exists($requestParams/record))
	then csd:filter_by_record($svcs1,$requestParams/record)
      else $svcs1

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items(svcs2,$requestParams/start,$requestParams/max)
	else csd:limit_items(svcs2,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items(svcs2,<start/>,$requestParams/max)
	else $svcs2

    }
  </serviceDirectory>
  <facilityDirectory/>
  <providerDirectory/>
</CSD>

};

(:~
: This is a module contatining the required stored queries for Care Services Discovery
: @version 1.0
: @see https://github.com/his-interop/openinfoman @see http://ihe.net
:
:)
module namespace csd_bsq = "https://github.com/his-interop/openinfoman/csd_bsq";

import module namespace csd = "urn:ihe:iti:csd:2013" at "csd_base_library.xqm";

declare default element  namespace   "urn:ihe:iti:csd:2013";

declare variable $csd_bsq:stored_functions :=
(
   <function uuid='4e8bbeb9-f5f5-11e2-b778-0800200c9a66'
   	     method='csd_bsq:provider_search'
 	     content-type='text/xml; charset=utf-8'
	     />,
   <function uuid='dc6aedf0-f609-11e2-b778-0800200c9a66'
   	     method='csd_bsq:organization_search'
 	     content-type='text/xml; charset=utf-8'
	     />,
   <function uuid='e3d8ecd0-f605-11e2-b778-0800200c9a66'
   	     method='csd_bsq:service_search'
 	     content-type='text/xml; charset=utf-8'
	     />,
   <function uuid='c7640530-f600-11e2-b778-0800200c9a66'
   	     method='csd_bsq:facility_search'
 	     content-type='text/xml; charset=utf-8'
	     />
);

declare function csd_bsq:provider_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory>
    {

      let $provs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/providerDirectory/*,$requestParams/id)
      else $doc/CSD/providerDirectory/*

      let $provs1 := if(exists($requestParams/otherID))
	then csd:filter_by_other_id($provs0,$requestParams/otherID)
      else $provs0

      let $provs2 := if(exists($requestParams/commonName))
	then csd:filter_by_common_name($provs1,$requestParams/commonName)
      else $provs1

      let $provs3 := if (exists($requestParams/codedType))
	then csd:filter_by_coded_type($provs2,$requestParams/codedType)
      else $provs2

      let $provs4 := if (exists($requestParams/address/addressLine))
	then csd:filter_by_address($provs3, $requestParams/address/addressLine)
      else $provs3

      let $provs5 :=  if (exists($requestParams/record))
	then csd:filter_by_record($provs4,$requestParams/record)
      else  $provs4

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items($provs5,$requestParams/start,$requestParams/max)
	else csd:limit_items($provs5,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items($provs5,<start/>,$requestParams/max)
	else $provs5

    }
  </providerDirectory>
</CSD>

};

declare function csd_bsq:organization_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory>
    {
      let $orgs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/organizationDirectory/*,$requestParams/id)
	else $doc/CSD/organizationDirectory/*

      let $orgs1 := if (exists($requestParams/primaryName))
	then csd:filter_by_primary_name($orgs0,$requestParams/primaryName)
      else $orgs0

      let $orgs2 := if(exists($requestParams/name))
	then csd:filter_by_name($orgs1,$requestParams/name)
      else $orgs1

      let $orgs3 := if(exists($requestParams/codedType))
	then csd:filter_by_coded_type($orgs2,$requestParams/codedType)
	else $orgs2

      let $orgs4 :=if (exists($requestParams/address/addressLine))
	then csd:filter_by_address($orgs3, $requestParams/address/addressLine)
	else $orgs3

      let $orgs5 := if (exists($requestParams/record))
	then csd:filter_by_record($orgs4,$requestParams/record)
      else $orgs4

      let $orgs6 := if (exists($requestParams/otherID))
	then csd:filter_by_other_id($orgs5,$requestParams/otherID)
      else $orgs5

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items($orgs6,$requestParams/start,$requestParams/max)
	else csd:limit_items($orgs6,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items($orgs6,<start/>,$requestParams/max)
	else $orgs6

    }
  </organizationDirectory>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory/>
</CSD>
};

declare function csd_bsq:facility_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory>
    {
      let $facs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/facilityDirectory/*,$requestParams/id)
      else $doc/CSD/facilityDirectory/*

      let $facs1 := if (exists($requestParams/primaryName))
	then csd:filter_by_primary_name($facs0,$requestParams/primaryName)
      else $facs0

      let $facs2 := if (exists($requestParams/name))
	then csd:filter_by_name($facs1,$requestParams/name)
      else $facs1

      let $facs3 := if(exists($requestParams/codedType))
	then csd:filter_by_coded_type($facs2,$requestParams/codedType)
      else $facs2

      let $facs4 := if(exists($requestParams/address/addressLine))
	then csd:filter_by_address($facs3, $requestParams/address/addressLine)
      else $facs3

      let $facs5 := if (exists($requestParams/record))
	then csd:filter_by_record($facs4,$requestParams/record)
      else $facs4

      let $facs6 := if(exists($requestParams/otherID))
	then csd:filter_by_other_id($facs5,$requestParams/otherID)
      else $facs5

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items($facs6,$requestParams/start,$requestParams/max)
	else csd:limit_items($facs6,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items($facs6,<start/>,$requestParams/max)
	else $facs6

    }
  </facilityDirectory>
  <providerDirectory/>
</CSD>
};

declare function csd_bsq:service_search($requestParams, $doc) as element()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory>
    {
      let $svcs0 := if (exists($requestParams/id))
	then csd:filter_by_primary_id($doc/CSD/serviceDirectory/*,$requestParams/id)
      else $doc/CSD/serviceDirectory/*

      let $svcs1 := if(exists($requestParams/codedType))
	then csd:filter_by_coded_type($svcs0,$requestParams/codedType)
      else $svcs0

      let $svcs2 :=  if (exists($requestParams/record))
	then csd:filter_by_record($svcs1,$requestParams/record)
      else $svcs1

      return if (exists($requestParams/start)) then
	if (exists($requestParams/max))
	  then csd:limit_items(svcs2,$requestParams/start,$requestParams/max)
	else csd:limit_items(svcs2,$requestParams/start,<max/>)
      else
	if (exists($requestParams/max))
	  then csd:limit_items(svcs2,<start/>,$requestParams/max)
	else svcs2

    }
  </serviceDirectory>
  <facilityDirectory/>
  <providerDirectory/>
</CSD>

};


MarkLogic: Create a local:eval-modules helper function.

(:
 : Copyright (C) 2018-2021 Reece H. Dunn
 :
 : 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.
 :)
xquery version "1.0-ml";

import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.xqy";

declare namespace o = "http://reecedunn.co.uk/xquery/options";
declare namespace eval = "xdmp:eval";

declare option o:implementation "marklogic/6.0";

(:~ Run a query on a MarkLogic server.
 :
 : @param $mode Whether to "run", "profile", or "debug" the query.
 : @param $mimetype The mimetype of the query.
 : @param $module-path The path of the module to invoke, or "" for evaluated scripts.
 : @param $query The query script to evaluate, or "" for invoked modules.
 : @param $vars A map of the variable values by the variable name.
 : @param $types A map of the variable types by the variable name.
 : @param $context-value The context item for XSLT queries as an XML object.
 : @param $context-path The context item for XSLT queries as a module file.
 : @param $rdf-output-format The mimetype to format sem:triple results as, or "" to leave them as is.
 : @param $updating An updating query if "true", or a non-updating query if "false".
 : @param $server The name of the server to use, or "" to not use a server.
 : @param $database The name of the database to use, or "" to not use a database.
 : @param $module-root The path to the server modules, or "" to use the default server value.
 :
 : This script has additional logic to map the semantics of the REST/XCC API to
 : the semantics of the API implemented in the xquery-intellij-plugin to support
 : the Run/Debug Configurations of the IntelliJ IDEs. Specifically:
 :
 : 1.  If there is an error, the REST API returns a "500 Internal Error" HTTP
 :     status. This catches the error and returns an element(err:error) object.
 :
 : 2.  The variables are passed via the REST API as xs:untypedAtomic. This
 :     converts the variables to the type they were specified as in the
 :     xquery-intellij-plugin API.
 :
 : 3.  The REST API only returns the primitive type of each item.
 :)

declare variable $mode as xs:string external := "run";
declare variable $mimetype as xs:string external := "application/xquery";
declare variable $module-path as xs:string external := "";
declare variable $query as xs:string external := "()";
declare variable $vars as xs:string external := "{}";
declare variable $types as xs:string external := "{}";
declare variable $context-value as xs:string external := "";
declare variable $context-path as xs:string external := "";
declare variable $rdf-output-format as xs:string external := "";
declare variable $updating as xs:string external := "false";
declare variable $server as xs:string external := "";
declare variable $database as xs:string external := "";
declare variable $module-root as xs:string external := "";

declare variable $content-type-header-prefix as xs:string external := "X-Content-Type-";
declare variable $derived-type-header-prefix as xs:string external := "X-Derived-";

declare function local:nullize($value) {
    if (string-length($value) eq 0) then () else $value
};

declare function local:version() {
    substring-before(xdmp:version(), "-") cast as xs:double
};

declare function local:version-minor() {
    substring-after(xdmp:version(), "-") cast as xs:double
};

declare function local:function($ref as xs:string) {
    try { xdmp:eval($ref) } catch * { () }
};

declare function local:server-coordinate-system($server as xs:unsignedLong?) {
    let $server-coordinate-system := local:function("xdmp:server-coordinate-system#1")
    return if (exists($server) and exists($server-coordinate-system)) then
        $server-coordinate-system($server)
    else
        ()
};

declare function local:item($path as xs:string, $value as xs:string, $type as xs:string) {
    if (string-length($value) ne 0) then
        xdmp:unquote($value)
    else if (string-length($path) ne 0) then
        doc($path)
    else
        ()
};

declare function local:cast-as($value, $type) {
    switch ($type)
    case "xs:anyURI" return $value cast as xs:anyURI
    case "xs:base64Binary" return $value cast as xs:base64Binary
    case "xs:boolean" return $value cast as xs:boolean
    case "xs:byte" return $value cast as xs:byte
    case "xs:date" return $value cast as xs:date
    case "xs:dateTime" return $value cast as xs:dateTime
    case "xs:dateTimeStamp" return $value cast as xs:dateTime (: MarkLogic does not support XML Schema 1.1 Part 2 :)
    case "xs:dayTimeDuration" return $value cast as xs:dayTimeDuration
    case "xs:decimal" return $value cast as xs:decimal
    case "xs:double" return $value cast as xs:double
    case "xs:duration" return $value cast as xs:duration
    case "xs:float" return $value cast as xs:float
    case "xs:gDay" return $value cast as xs:gDay
    case "xs:gMonth" return $value cast as xs:gMonth
    case "xs:gMonthDay" return $value cast as xs:gMonthDay
    case "xs:gYear" return $value cast as xs:gYear
    case "xs:gYearMonth" return $value cast as xs:gYearMonth
    case "xs:hexBinary" return $value cast as xs:hexBinary
    case "xs:int" return $value cast as xs:int
    case "xs:integer" return $value cast as xs:integer
    case "xs:language" return $value cast as xs:language
    case "xs:long" return $value cast as xs:long
    case "xs:negativeInteger" return $value cast as xs:negativeInteger
    case "xs:nonNegativeInteger" return $value cast as xs:nonNegativeInteger
    case "xs:nonPositiveInteger" return $value cast as xs:nonPositiveInteger
    case "xs:normalizedString" return $value cast as xs:normalizedString
    case "xs:numeric" return $value cast as xs:numeric
    case "xs:positiveInteger" return $value cast as xs:positiveInteger
    case "xs:short" return $value cast as xs:short
    case "xs:string" return $value cast as xs:string
    case "xs:time" return $value cast as xs:time
    case "xs:token" return $value cast as xs:token
    case "xs:unsignedByte" return $value cast as xs:unsignedByte
    case "xs:unsignedInt" return $value cast as xs:unsignedInt
    case "xs:unsignedLong" return $value cast as xs:unsignedLong
    case "xs:unsignedShort" return $value cast as xs:unsignedShort
    case "xs:yearMonthDuration" return $value cast as xs:yearMonthDuration
    case "xs:ENTITY" return $value cast as xs:ENTITY
    case "xs:ID" return $value cast as xs:ID
    case "xs:IDREF" return $value cast as xs:IDREF
    case "xs:Name" return $value cast as xs:Name
    case "xs:NCName" return $value cast as xs:NCName
    case "xs:NMTOKEN" return $value cast as xs:NMTOKEN
    case "xs:QName" return $value cast as xs:QName
    default return $value
};

declare function local:parse-vars($values as map:map, $types as map:map) as item()* {
    for $key in map:keys($values)
    let $value := local:cast-as(map:get($values, $key), map:get($types, $key))
    return (xs:QName($key), $value)
};

declare function local:parse-vars-map($values as map:map, $types as map:map) as map:map {
    let $ret := map:map()
    let $_ :=
        for $key in map:keys($values)
        let $value := local:cast-as(map:get($values, $key), map:get($types, $key))
        return map:put($ret, $key, $value)
    return $ret
};

declare function local:derived-type-name($value) {
    (: NOTE: Ordering is important here -- reverse type hierarchy :)
    typeswitch ($value)
    case function(*) return "function(*)"
    (: xs:integer derived types :)
    case xs:positiveInteger return "xs:positiveInteger"
    case xs:unsignedByte return "xs:unsignedByte"
    case xs:unsignedShort return "xs:unsignedShort"
    case xs:unsignedInt return "xs:unsignedInt"
    case xs:unsignedLong return "xs:unsignedLong"
    case xs:nonNegativeInteger return "xs:nonNegativeInteger"
    case xs:byte return "xs:byte"
    case xs:short return "xs:short"
    case xs:int return "xs:int"
    case xs:long return "xs:long"
    case xs:negativeInteger return "xs:negativeInteger"
    case xs:nonPositiveInteger return "xs:nonPositiveInteger"
    (: xs:string derived types :)
    case xs:ENTITY return "xs:ENTITY"
    case xs:IDREF return "xs:IDREF"
    case xs:ID return "xs:ID"
    case xs:NCName return "xs:NCName"
    case xs:Name return "xs:Name"
    case xs:NMTOKEN return "xs:NMTOKEN"
    case xs:language return "xs:language"
    case xs:token return "xs:token"
    case xs:normalizedString return "xs:normalizedString"
    default return () (: primitive type, so does not need the type name to be specified. :)
};

declare function local:rdf-format($mimetype) {
    switch ($mimetype)
    case "application/n-quads" return "nquad"
    case "application/n-triples" return "ntriple"
    case "application/rdf+json" return "rdfjson"
    case "application/rdf+xml" return "rdfxml"
    case "application/trig" return "trig"
    case "application/vnd.marklogic.triples+xml" return "triplexml"
    case "text/n3" return "n3"
    case "text/turtle" return "turtle"
    default return fn:error("UNSUPPORTED-RDF-FORMAT", "Unsupported RDF format: " || $mimetype)
};

declare function local:use-modules-root($server-root) {
    exists($server-root) and string-length($module-root) ne 0 and not($module-root eq $server-root)
};

declare function local:eval-static-check($static-check as xs:boolean) {
    <eval:static-check>{$static-check}</eval:static-check>
};

declare function local:eval-database($database as xs:unsignedLong?) {
    if (exists($database)) then
        <eval:database>{$database}</eval:database>
    else
        ()
};

declare function local:eval-default-collation($collation as xs:string?) {
    if (exists($collation)) then
        <eval:default-collation>{$collation}</eval:default-collation>
    else
        ()
};

declare function local:eval-default-coordinate-system($coordinate-system as xs:string?) {
    if (exists($coordinate-system)) then
        <eval:default-coordinate-system>{$coordinate-system}</eval:default-coordinate-system>
    else
        ()
};

declare function local:eval-default-xquery-version($xquery-version as xs:string?) {
    if (exists($xquery-version) and $mimetype eq "application/xquery") then
        <eval:default-xquery-version>{$xquery-version}</eval:default-xquery-version>
    else
        ()
};

declare function local:eval-modules($database as xs:unsignedLong?) {
    if (exists($database)) then
        <eval:modules>{$database}</eval:modules>
    else
        ()
};

declare function local:eval-options() {
    let $server := local:nullize($server) ! xdmp:server(.)
    let $database :=
        let $id := local:nullize($database) ! xdmp:database(.)
        return if (exists($id)) then
            $id
        else if (exists($server)) then
            xdmp:server-database($server)
        else
            ()
    return <eval:options>{
        local:eval-static-check($mode eq "validate"),
        local:eval-database($database),
        local:eval-default-collation($server ! xdmp:server-collation(.)),
        local:eval-default-coordinate-system($server ! local:server-coordinate-system(.)),
        local:eval-default-xquery-version($server ! xdmp:server-default-xquery-version($server)),
        let $server-root := $server ! xdmp:server-root(.)
        return if (local:use-modules-root($server-root)) then
            (local:eval-modules(0), <eval:root>{$module-root}</eval:root>) (: file system :)
        else
            (), (: use the default server settings :)
        let $major := local:version()
        let $minor := local:version-minor()
        return if ($mode = "debug") then
            if ($updating = "true") then
                fn:error(xs:QName("err:FOER0000"), "Debugging an update query is not supported by MarkLogic.")
            else
                ()
        else if ($major lt 7.0 or ($major eq 8.0 and $minor lt 7.0) or ($major eq 9.0 and $minor lt 2.0)) then
            if ($updating = "true") then
                <eval:transaction-mode>update</eval:transaction-mode>
            else
                <eval:transaction-mode>query</eval:transaction-mode>
        else
            (: MarkLogic 8.0-7 and 9.0-2 support <update> :)
            <eval:update>{$updating}</eval:update>
    }</eval:options>
};

declare function local:javascript() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $options := local:eval-options()
    return if (local:version() < 8.0) then
        fn:error(
            xs:QName("UNSUPPORTED-VERSION"),
            "MarkLogic " || xdmp:version() || " does not support server-side JavaScript"
        )
    else if (string-length($query) ne 0) then
        switch ($mode)
        case "run" return
            let $f := local:function("xdmp:javascript-eval#3")
            let $start := xdmp:elapsed-time()
            let $ret := $f($query, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        default return ()
    else
        switch ($mode)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:invoke($module-path, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        default return ()
};

declare function local:sparql-query() as item()* {
    let $variables := local:parse-vars-map(xdmp:unquote($vars), xdmp:unquote($types))
    let $query :=
        if (string-length($query) ne 0) then
            $query
        else
            () (: TODO: Read the contents of the query file from the modules database. :)
    return switch ($mode)
    case "run" return
        let $start := xdmp:elapsed-time()
        let $ret := sem:sparql($query, $variables)
        return (xdmp:elapsed-time() - $start, $ret)
    default return ()
};

declare function local:sparql-update() as item()* {
    let $variables := local:parse-vars-map(xdmp:unquote($vars), xdmp:unquote($types))
    let $query :=
        if (string-length($query) ne 0) then
            $query
        else
            () (: TODO: Read the contents of the query file from the modules database. :)
    return if (local:version() < 8.0) then
        fn:error(
            xs:QName("UNSUPPORTED-VERSION"),
            "MarkLogic " || xdmp:version() || " does not support SPARQL update queries"
        )
    else switch ($mode)
    case "run" return
        let $start := xdmp:elapsed-time()
        let $ret := sem:sparql-update($query, $variables)
        return (xdmp:elapsed-time() - $start, $ret)
    default return ()
};

declare function local:sql() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $query :=
        if (string-length($query) ne 0) then
            $query
        else
            () (: TODO: Read the contents of the query file from the modules database. :)
    return switch ($mode)
    case "run" return
        if (local:version() < 9.0) then
            let $f := local:function("xdmp:sql#1")
            let $start := xdmp:elapsed-time()
            let $ret := $f($query)
            return (xdmp:elapsed-time() - $start, $ret)
        else
            let $f := local:function("xdmp:sql#3")
            let $start := xdmp:elapsed-time()
            let $ret := $f($query, (), $variables)
            return (xdmp:elapsed-time() - $start, $ret)
    default return ()
};

declare function local:xquery() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $options := local:eval-options()
    return if (string-length($query) ne 0) then
        switch ($mode)
        case "debug" return dbg:eval($query, $variables, $options)
        case "profile" return prof:eval($query, $variables, $options)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:eval($query, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:eval($query, $variables, $options)
        default return ()
    else
        switch ($mode)
        case "debug" return dbg:invoke($module-path, $variables, $options)
        case "profile" return prof:invoke($module-path, $variables, $options)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:invoke($module-path, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:invoke($module-path, $variables, $options)
        default return ()
};

declare function local:xslt() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $input := local:item($context-path, $context-value, "application/xml")
    let $options := local:eval-options()
    return if (string-length($query) ne 0) then
        switch ($mode)
        case "profile" return prof:xslt-eval(xdmp:unquote($query), $input, $variables, $options)
        case "run" return
            let $query := xdmp:unquote($query)
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:xslt-eval($query, $input, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:xslt-eval(xdmp:unquote($query), $input, $variables, $options)
        default return ()
    else
        switch ($mode)
        case "profile" return prof:xslt-invoke($module-path, $input, $variables, $options)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:xslt-invoke($module-path, $input, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:xslt-invoke($module-path, $input, $variables, $options)
        default return ()
};

try {
    let $retvals :=
        switch ($mimetype)
        case "application/sparql-query" return local:sparql-query()
        case "application/sparql-update" return local:sparql-update()
        case "application/sql" return local:sql()
        case "application/vnd.marklogic-javascript" return local:javascript()
        case "application/xquery" return local:xquery()
        case "application/xslt+xml" return local:xslt()
        default return ()
    let $triples := for $item in $retvals where $item instance of sem:triple return $item
    let $retvals := for $item in $retvals where not($item instance of sem:triple) return $item
    return if (exists($triples) and $rdf-output-format ne "") then
        let $rdf-output := sem:rdf-serialize($triples, local:rdf-format($rdf-output-format))
        let $_ := xdmp:add-response-header($content-type-header-prefix || (count($retvals) + 1), $rdf-output-format)
        return (
            for $retval at $i in $retvals
            let $_ := local:derived-type-name($retval) ! xdmp:add-response-header($derived-type-header-prefix || $i, .)
            return $retval,
            $rdf-output
        )
    else
        for $retval at $i in ($retvals, $triples)
        let $_ := local:derived-type-name($retval) ! xdmp:add-response-header($derived-type-header-prefix || $i, .)
        return $retval
} catch * {
    let $_ := xdmp:add-response-header($derived-type-header-prefix || 1, "err:error")
    return $err:additional
}

(:
 : Copyright (C) 2018-2021 Reece H. Dunn
 :
 : 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.
 :)
xquery version "1.0-ml";

import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.xqy";

declare namespace o = "http://reecedunn.co.uk/xquery/options";
declare namespace eval = "xdmp:eval";

declare option o:implementation "marklogic/6.0";

(:~ Run a query on a MarkLogic server.
 :
 : @param $mode Whether to "run", "profile", or "debug" the query.
 : @param $mimetype The mimetype of the query.
 : @param $module-path The path of the module to invoke, or "" for evaluated scripts.
 : @param $query The query script to evaluate, or "" for invoked modules.
 : @param $vars A map of the variable values by the variable name.
 : @param $types A map of the variable types by the variable name.
 : @param $context-value The context item for XSLT queries as an XML object.
 : @param $context-path The context item for XSLT queries as a module file.
 : @param $rdf-output-format The mimetype to format sem:triple results as, or "" to leave them as is.
 : @param $updating An updating query if "true", or a non-updating query if "false".
 : @param $server The name of the server to use, or "" to not use a server.
 : @param $database The name of the database to use, or "" to not use a database.
 : @param $module-root The path to the server modules, or "" to use the default server value.
 :
 : This script has additional logic to map the semantics of the REST/XCC API to
 : the semantics of the API implemented in the xquery-intellij-plugin to support
 : the Run/Debug Configurations of the IntelliJ IDEs. Specifically:
 :
 : 1.  If there is an error, the REST API returns a "500 Internal Error" HTTP
 :     status. This catches the error and returns an element(err:error) object.
 :
 : 2.  The variables are passed via the REST API as xs:untypedAtomic. This
 :     converts the variables to the type they were specified as in the
 :     xquery-intellij-plugin API.
 :
 : 3.  The REST API only returns the primitive type of each item.
 :)

declare variable $mode as xs:string external := "run";
declare variable $mimetype as xs:string external := "application/xquery";
declare variable $module-path as xs:string external := "";
declare variable $query as xs:string external := "()";
declare variable $vars as xs:string external := "{}";
declare variable $types as xs:string external := "{}";
declare variable $context-value as xs:string external := "";
declare variable $context-path as xs:string external := "";
declare variable $rdf-output-format as xs:string external := "";
declare variable $updating as xs:string external := "false";
declare variable $server as xs:string external := "";
declare variable $database as xs:string external := "";
declare variable $module-root as xs:string external := "";

declare variable $content-type-header-prefix as xs:string external := "X-Content-Type-";
declare variable $derived-type-header-prefix as xs:string external := "X-Derived-";

declare function local:nullize($value) {
    if (string-length($value) eq 0) then () else $value
};

declare function local:version() {
    substring-before(xdmp:version(), "-") cast as xs:double
};

declare function local:version-minor() {
    substring-after(xdmp:version(), "-") cast as xs:double
};

declare function local:function($ref as xs:string) {
    try { xdmp:eval($ref) } catch * { () }
};

declare function local:server-coordinate-system($server as xs:unsignedLong?) {
    let $server-coordinate-system := local:function("xdmp:server-coordinate-system#1")
    return if (exists($server) and exists($server-coordinate-system)) then
        $server-coordinate-system($server)
    else
        ()
};

declare function local:item($path as xs:string, $value as xs:string, $type as xs:string) {
    if (string-length($value) ne 0) then
        xdmp:unquote($value)
    else if (string-length($path) ne 0) then
        doc($path)
    else
        ()
};

declare function local:cast-as($value, $type) {
    switch ($type)
    case "xs:anyURI" return $value cast as xs:anyURI
    case "xs:base64Binary" return $value cast as xs:base64Binary
    case "xs:boolean" return $value cast as xs:boolean
    case "xs:byte" return $value cast as xs:byte
    case "xs:date" return $value cast as xs:date
    case "xs:dateTime" return $value cast as xs:dateTime
    case "xs:dateTimeStamp" return $value cast as xs:dateTime (: MarkLogic does not support XML Schema 1.1 Part 2 :)
    case "xs:dayTimeDuration" return $value cast as xs:dayTimeDuration
    case "xs:decimal" return $value cast as xs:decimal
    case "xs:double" return $value cast as xs:double
    case "xs:duration" return $value cast as xs:duration
    case "xs:float" return $value cast as xs:float
    case "xs:gDay" return $value cast as xs:gDay
    case "xs:gMonth" return $value cast as xs:gMonth
    case "xs:gMonthDay" return $value cast as xs:gMonthDay
    case "xs:gYear" return $value cast as xs:gYear
    case "xs:gYearMonth" return $value cast as xs:gYearMonth
    case "xs:hexBinary" return $value cast as xs:hexBinary
    case "xs:int" return $value cast as xs:int
    case "xs:integer" return $value cast as xs:integer
    case "xs:language" return $value cast as xs:language
    case "xs:long" return $value cast as xs:long
    case "xs:negativeInteger" return $value cast as xs:negativeInteger
    case "xs:nonNegativeInteger" return $value cast as xs:nonNegativeInteger
    case "xs:nonPositiveInteger" return $value cast as xs:nonPositiveInteger
    case "xs:normalizedString" return $value cast as xs:normalizedString
    case "xs:numeric" return $value cast as xs:numeric
    case "xs:positiveInteger" return $value cast as xs:positiveInteger
    case "xs:short" return $value cast as xs:short
    case "xs:string" return $value cast as xs:string
    case "xs:time" return $value cast as xs:time
    case "xs:token" return $value cast as xs:token
    case "xs:unsignedByte" return $value cast as xs:unsignedByte
    case "xs:unsignedInt" return $value cast as xs:unsignedInt
    case "xs:unsignedLong" return $value cast as xs:unsignedLong
    case "xs:unsignedShort" return $value cast as xs:unsignedShort
    case "xs:yearMonthDuration" return $value cast as xs:yearMonthDuration
    case "xs:ENTITY" return $value cast as xs:ENTITY
    case "xs:ID" return $value cast as xs:ID
    case "xs:IDREF" return $value cast as xs:IDREF
    case "xs:Name" return $value cast as xs:Name
    case "xs:NCName" return $value cast as xs:NCName
    case "xs:NMTOKEN" return $value cast as xs:NMTOKEN
    case "xs:QName" return $value cast as xs:QName
    default return $value
};

declare function local:parse-vars($values as map:map, $types as map:map) as item()* {
    for $key in map:keys($values)
    let $value := local:cast-as(map:get($values, $key), map:get($types, $key))
    return (xs:QName($key), $value)
};

declare function local:parse-vars-map($values as map:map, $types as map:map) as map:map {
    let $ret := map:map()
    let $_ :=
        for $key in map:keys($values)
        let $value := local:cast-as(map:get($values, $key), map:get($types, $key))
        return map:put($ret, $key, $value)
    return $ret
};

declare function local:derived-type-name($value) {
    (: NOTE: Ordering is important here -- reverse type hierarchy :)
    typeswitch ($value)
    case function(*) return "function(*)"
    (: xs:integer derived types :)
    case xs:positiveInteger return "xs:positiveInteger"
    case xs:unsignedByte return "xs:unsignedByte"
    case xs:unsignedShort return "xs:unsignedShort"
    case xs:unsignedInt return "xs:unsignedInt"
    case xs:unsignedLong return "xs:unsignedLong"
    case xs:nonNegativeInteger return "xs:nonNegativeInteger"
    case xs:byte return "xs:byte"
    case xs:short return "xs:short"
    case xs:int return "xs:int"
    case xs:long return "xs:long"
    case xs:negativeInteger return "xs:negativeInteger"
    case xs:nonPositiveInteger return "xs:nonPositiveInteger"
    (: xs:string derived types :)
    case xs:ENTITY return "xs:ENTITY"
    case xs:IDREF return "xs:IDREF"
    case xs:ID return "xs:ID"
    case xs:NCName return "xs:NCName"
    case xs:Name return "xs:Name"
    case xs:NMTOKEN return "xs:NMTOKEN"
    case xs:language return "xs:language"
    case xs:token return "xs:token"
    case xs:normalizedString return "xs:normalizedString"
    default return () (: primitive type, so does not need the type name to be specified. :)
};

declare function local:rdf-format($mimetype) {
    switch ($mimetype)
    case "application/n-quads" return "nquad"
    case "application/n-triples" return "ntriple"
    case "application/rdf+json" return "rdfjson"
    case "application/rdf+xml" return "rdfxml"
    case "application/trig" return "trig"
    case "application/vnd.marklogic.triples+xml" return "triplexml"
    case "text/n3" return "n3"
    case "text/turtle" return "turtle"
    default return fn:error("UNSUPPORTED-RDF-FORMAT", "Unsupported RDF format: " || $mimetype)
};

declare function local:use-modules-root($server-root) {
    exists($server-root) and string-length($module-root) ne 0 and not($module-root eq $server-root)
};

declare function local:eval-static-check($static-check as xs:boolean) {
    <eval:static-check>{$static-check}</eval:static-check>
};

declare function local:eval-database($database as xs:unsignedLong?) {
    if (exists($database)) then
        <eval:database>{$database}</eval:database>
    else
        ()
};

declare function local:eval-default-collation($collation as xs:string?) {
    if (exists($collation)) then
        <eval:default-collation>{$collation}</eval:default-collation>
    else
        ()
};

declare function local:eval-default-coordinate-system($coordinate-system as xs:string?) {
    if (exists($coordinate-system)) then
        <eval:default-coordinate-system>{$coordinate-system}</eval:default-coordinate-system>
    else
        ()
};

declare function local:eval-default-xquery-version($xquery-version as xs:string?) {
    if (exists($xquery-version) and $mimetype eq "application/xquery") then
        <eval:default-xquery-version>{$xquery-version}</eval:default-xquery-version>
    else
        ()
};

declare function local:eval-options() {
    let $server := local:nullize($server) ! xdmp:server(.)
    let $database :=
        let $id := local:nullize($database) ! xdmp:database(.)
        return if (exists($id)) then
            $id
        else if (exists($server)) then
            xdmp:server-database($server)
        else
            ()
    return <eval:options>{
        local:eval-static-check($mode eq "validate"),
        local:eval-database($database),
        local:eval-default-collation($server ! xdmp:server-collation(.)),
        local:eval-default-coordinate-system($server ! local:server-coordinate-system(.)),
        local:eval-default-xquery-version($server ! xdmp:server-default-xquery-version($server)),
        let $server-root := $server ! xdmp:server-root(.)
        return if (local:use-modules-root($server-root)) then
            (<eval:modules>0</eval:modules>, <eval:root>{$module-root}</eval:root>) (: file system :)
        else
            (), (: use the default server settings :)
        let $major := local:version()
        let $minor := local:version-minor()
        return if ($mode = "debug") then
            if ($updating = "true") then
                fn:error(xs:QName("err:FOER0000"), "Debugging an update query is not supported by MarkLogic.")
            else
                ()
        else if ($major lt 7.0 or ($major eq 8.0 and $minor lt 7.0) or ($major eq 9.0 and $minor lt 2.0)) then
            if ($updating = "true") then
                <eval:transaction-mode>update</eval:transaction-mode>
            else
                <eval:transaction-mode>query</eval:transaction-mode>
        else
            (: MarkLogic 8.0-7 and 9.0-2 support <update> :)
            <eval:update>{$updating}</eval:update>
    }</eval:options>
};

declare function local:javascript() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $options := local:eval-options()
    return if (local:version() < 8.0) then
        fn:error(
            xs:QName("UNSUPPORTED-VERSION"),
            "MarkLogic " || xdmp:version() || " does not support server-side JavaScript"
        )
    else if (string-length($query) ne 0) then
        switch ($mode)
        case "run" return
            let $f := local:function("xdmp:javascript-eval#3")
            let $start := xdmp:elapsed-time()
            let $ret := $f($query, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        default return ()
    else
        switch ($mode)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:invoke($module-path, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        default return ()
};

declare function local:sparql-query() as item()* {
    let $variables := local:parse-vars-map(xdmp:unquote($vars), xdmp:unquote($types))
    let $query :=
        if (string-length($query) ne 0) then
            $query
        else
            () (: TODO: Read the contents of the query file from the modules database. :)
    return switch ($mode)
    case "run" return
        let $start := xdmp:elapsed-time()
        let $ret := sem:sparql($query, $variables)
        return (xdmp:elapsed-time() - $start, $ret)
    default return ()
};

declare function local:sparql-update() as item()* {
    let $variables := local:parse-vars-map(xdmp:unquote($vars), xdmp:unquote($types))
    let $query :=
        if (string-length($query) ne 0) then
            $query
        else
            () (: TODO: Read the contents of the query file from the modules database. :)
    return if (local:version() < 8.0) then
        fn:error(
            xs:QName("UNSUPPORTED-VERSION"),
            "MarkLogic " || xdmp:version() || " does not support SPARQL update queries"
        )
    else switch ($mode)
    case "run" return
        let $start := xdmp:elapsed-time()
        let $ret := sem:sparql-update($query, $variables)
        return (xdmp:elapsed-time() - $start, $ret)
    default return ()
};

declare function local:sql() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $query :=
        if (string-length($query) ne 0) then
            $query
        else
            () (: TODO: Read the contents of the query file from the modules database. :)
    return switch ($mode)
    case "run" return
        if (local:version() < 9.0) then
            let $f := local:function("xdmp:sql#1")
            let $start := xdmp:elapsed-time()
            let $ret := $f($query)
            return (xdmp:elapsed-time() - $start, $ret)
        else
            let $f := local:function("xdmp:sql#3")
            let $start := xdmp:elapsed-time()
            let $ret := $f($query, (), $variables)
            return (xdmp:elapsed-time() - $start, $ret)
    default return ()
};

declare function local:xquery() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $options := local:eval-options()
    return if (string-length($query) ne 0) then
        switch ($mode)
        case "debug" return dbg:eval($query, $variables, $options)
        case "profile" return prof:eval($query, $variables, $options)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:eval($query, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:eval($query, $variables, $options)
        default return ()
    else
        switch ($mode)
        case "debug" return dbg:invoke($module-path, $variables, $options)
        case "profile" return prof:invoke($module-path, $variables, $options)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:invoke($module-path, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:invoke($module-path, $variables, $options)
        default return ()
};

declare function local:xslt() as item()* {
    let $variables := local:parse-vars(xdmp:unquote($vars), xdmp:unquote($types))
    let $input := local:item($context-path, $context-value, "application/xml")
    let $options := local:eval-options()
    return if (string-length($query) ne 0) then
        switch ($mode)
        case "profile" return prof:xslt-eval(xdmp:unquote($query), $input, $variables, $options)
        case "run" return
            let $query := xdmp:unquote($query)
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:xslt-eval($query, $input, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:xslt-eval(xdmp:unquote($query), $input, $variables, $options)
        default return ()
    else
        switch ($mode)
        case "profile" return prof:xslt-invoke($module-path, $input, $variables, $options)
        case "run" return
            let $start := xdmp:elapsed-time()
            let $ret := xdmp:xslt-invoke($module-path, $input, $variables, $options)
            return (xdmp:elapsed-time() - $start, $ret)
        case "validate" return xdmp:xslt-invoke($module-path, $input, $variables, $options)
        default return ()
};

try {
    let $retvals :=
        switch ($mimetype)
        case "application/sparql-query" return local:sparql-query()
        case "application/sparql-update" return local:sparql-update()
        case "application/sql" return local:sql()
        case "application/vnd.marklogic-javascript" return local:javascript()
        case "application/xquery" return local:xquery()
        case "application/xslt+xml" return local:xslt()
        default return ()
    let $triples := for $item in $retvals where $item instance of sem:triple return $item
    let $retvals := for $item in $retvals where not($item instance of sem:triple) return $item
    return if (exists($triples) and $rdf-output-format ne "") then
        let $rdf-output := sem:rdf-serialize($triples, local:rdf-format($rdf-output-format))
        let $_ := xdmp:add-response-header($content-type-header-prefix || (count($retvals) + 1), $rdf-output-format)
        return (
            for $retval at $i in $retvals
            let $_ := local:derived-type-name($retval) ! xdmp:add-response-header($derived-type-header-prefix || $i, .)
            return $retval,
            $rdf-output
        )
    else
        for $retval at $i in ($retvals, $triples)
        let $_ := local:derived-type-name($retval) ! xdmp:add-response-header($derived-type-header-prefix || $i, .)
        return $retval
} catch * {
    let $_ := xdmp:add-response-header($derived-type-header-prefix || 1, "err:error")
    return $err:additional
}


Add notes to example

Add notes to example

xquery version "3.1";

(: Contact List example (from Reagent tutorial) :)

(:
 : An incomplete experiment of rendering UI using a React/Reagent approach.
 :
 : Intended to be used in a client, may be somewhat userful with Saxon-CE
 : but not in itself. It's main use is seeing how components could be added
 : to mu. [fn, args] to be executed later. Or in an SVG context or schema. These components
 : are parts in the mu data structures.
 : render#1 could be implemented maybe via the walk pattern.
 : Not sure what it's relationship with apply#
 : Another insight is that embedding functions on attributes could make the template
 : structure react to message e.g. send on on-click to an element causes an effect and
 : could result in a different "DOM" or mu-doc. Reactive documents in a render loop.
 :)
module namespace ex = 'http://xokomola.com/xquery/origami/examples';

import module namespace o = 'http://xokomola.com/xquery/origami/mu' at '../mu.xqm';

declare variable $ex:state :=
    map { 'contacts':
        [
            map { 'first': 'Ben', 'last': 'Bitdiddle', 'email': 'benb@mit.edu' },
            map { 'first': 'Alyssa', 'middleinitial': 'P', 'last': 'Hacker', 'email': 'aphacker@mit.edu' },
            map { 'first': 'Eva', 'middle': 'Lu', 'last': 'Ator', 'email': 'eval@mit.edu' },
            map { 'first': 'Louis', 'last': 'Reasoner', 'email': 'prolog@mit.edu' },
            map { 'first': 'Cy', 'middleinitial': 'D', 'last': 'Effect', 'email': 'bugs@mit.edu' },
            map { 'first': 'Lem', 'middleinitial': 'E', 'last': 'Tweakit', 'email': 'morebugs@mit.edu' }
        ]
    };

declare function ex:display-name($c)
{
    concat($c('last'), ', ', $c('first'))
};

declare function ex:add-contact($c)
{
    'Adding ' || ex:display-name($c)
};

declare function ex:remove-contact($c)
{
    'Removing ' || ex:display-name($c)
};

declare function ex:contact($c)
{
    ['li',
        ['span', ex:display-name($c)],
        ['button', map { 'on-click': function($c) { ex:remove-contact($c) }}, 'Delete']
    ]
};

declare function ex:contact-list()
{
    ['div',
        ['h1', 'Contact List'],
        ['ul', function() {
                for $c in $ex:state?contacts?*
                return [ex:contact#1, $c]
            }
        ],
        [ex:new-contact#0]
    ]
};

declare function ex:new-contact()
{
    ['div',
        ['input', map {
            'type': 'text',
            'placeholder': 'Contact Name',
            'value': '',
            'on-change': '' }],
        ['button', map { 'on-click': function($name) { ex:add-contact($name) }}, 'Add']
    ]
};

xquery version "3.1";

(: Contact List example (from Reagent tutorial) :)

(:
 : An incomplete experiment of rendering UI using a React/Reagent approach.
 :
 : Intended to be used in a client, may be somewhat userful with Saxon-CE
 : but not in itself. It's main use is seeing how components could be added
 : to mu. [fn, args] to be executed later. Or in an SVG context or schema. These components
 : are parts in the mu data structures.
 : render#1 could be implemented maybe via the walk pattern.
 : Not sure what it's relationship with apply#
 :)
module namespace ex = 'http://xokomola.com/xquery/origami/examples';

import module namespace o = 'http://xokomola.com/xquery/origami/mu' at '../mu.xqm';

declare variable $ex:state :=
    map { 'contacts':
        [
            map { 'first': 'Ben', 'last': 'Bitdiddle', 'email': 'benb@mit.edu' },
            map { 'first': 'Alyssa', 'middleinitial': 'P', 'last': 'Hacker', 'email': 'aphacker@mit.edu' },
            map { 'first': 'Eva', 'middle': 'Lu', 'last': 'Ator', 'email': 'eval@mit.edu' },
            map { 'first': 'Louis', 'last': 'Reasoner', 'email': 'prolog@mit.edu' },
            map { 'first': 'Cy', 'middleinitial': 'D', 'last': 'Effect', 'email': 'bugs@mit.edu' },
            map { 'first': 'Lem', 'middleinitial': 'E', 'last': 'Tweakit', 'email': 'morebugs@mit.edu' }
        ]
    };

declare function ex:display-name($c)
{
    concat($c('last'), ', ', $c('first'))
};

declare function ex:add-contact($c)
{
    'Adding ' || ex:display-name($c)
};

declare function ex:remove-contact($c)
{
    'Removing ' || ex:display-name($c)
};

declare function ex:contact($c)
{
    ['li',
        ['span', ex:display-name($c)],
        ['button', map { 'on-click': function($c) { ex:remove-contact($c) }}, 'Delete']
    ]
};

declare function ex:contact-list()
{
    ['div',
        ['h1', 'Contact List'],
        ['ul', function() {
                for $c in $ex:state?contacts?*
                return [ex:contact#1, $c]
            }
        ],
        [ex:new-contact#0]
    ]
};

declare function ex:new-contact()
{
    ['div',
        ['input', map {
            'type': 'text',
            'placeholder': 'Contact Name',
            'value': '',
            'on-change': '' }],
        ['button', map { 'on-click': function($name) { ex:add-contact($name) }}, 'Add']
    ]
};