From 3145c35ff29b3352860e78ea739836b3fcff96b9 Mon Sep 17 00:00:00 2001
From: michalovadek First we obtain the available data on Council votes using
- Excluding votes where all governments voted in favour, we are left
-with between To highlight that votes against tend to represent a strong signal of
-disagreement, the following simple formula is used to calculate the
-weighted proportion of Member State discontent: \(p_i = \frac{\sum_j^a{\text{infavour}_{ij}} -
-\sum_k^b{\text{abstain}_{ik}} - \sum_l^c{\text{against}_{il} * 2}}{a + b
-+ c}\) The data on votes are easy enough to plot interactively with
- The country comparison reveals substantial variation in the frequency
-of disagreement. The only Member State to ever exit the EU, the United
-Kingdom, was particularly active when it comes to abstaining or voting
-against legislation. On the other end of the scale is France, which has
-been happy to support almost every law or Council position put in front
-of it. We are unable to tell from this simple comparison whether a
-supportive voting record reflects satisfaction with the negotiated
-substance or governments’ overall stance on European integration (or
-both). A more sophisticated way of scaling Member States’ preferences would
-involve deriving their ideal points from the votes through an
-item-response model.1 In our example, we assume that all votes
-are equally informative and important; ideally, we would want to relax
-this assumption. An example application of an ideal point IRT model can
-be found in this
-paper.↩︎ The package also contains largely self-explanatory functions for
retrieving data on EU court cases (Voting in the Council of the EU
practice, it often decides by consensus, as Member States tend to avoid
open disagreements. Still, enough votes are taken to give us some
insight into the variation in Member State governments’ behaviour. We
-access these through a dedicated API maintained by the Council, which is
-also wrapped in the eurlex
package.
-Data on Council votes
-
-eurlex::elx_council_votes()
and process the API
-response.
-
# packages
-library(eurlex)
-library(ggplot2)
-library(dplyr)
-#>
-#> Attaching package: 'dplyr'
-#> The following objects are masked from 'package:stats':
-#>
-#> filter, lag
-#> The following objects are masked from 'package:base':
-#>
-#> intersect, setdiff, setequal, union
-library(tidyr)
-library(stringr)
-library(ggiraph)
-
-# pull Council voting data
-cns_votes_raw <- elx_council_votes()
-
-# vote level, keep only votes with disagreements
-votes_dis <- cns_votes_raw %>%
- select(voteProc, starts_with("countryCode")) %>%
- select(-countryCodeNotParticipatingGrouped) %>%
- distinct() %>%
- filter((!is.na(countryCodeAgainstGrouped) & !is.na(countryCodeAbstainedGrouped))) %>%
- pivot_longer(cols = starts_with("country"), names_to = "vote", values_to = "country") %>%
- separate_rows(country, sep = "\\|") %>%
- drop_na() %>%
- mutate(vote = case_when(str_detect(vote, "Favour") ~ 1L,
- str_detect(vote, "Absta") ~ 2L,
- str_detect(vote, "Against") ~ 3L,
- T ~ NA_integer_))
-
-# country vote counts
-country_votes_n <- votes_dis %>%
- count(country, vote)
-
-# weighted vote proportion
-country_votes_prop <- country_votes_n %>%
- mutate(value = case_when(vote == 1 ~ n * 1,
- vote == 2 ~ n * -1,
- vote == 3 ~ n * -2)) %>%
- group_by(country) %>%
- summarise(value = sum(value),
- n_votes = sum(n),
- prop = round(value / n_votes, 3)) %>%
- ungroup()
110
and 81
votes per Member
-State. While these numbers do not represent the entire historical voting
-record, they should still help us lift the veil on variation in Member
-States’ propensity to disagree. Note that due to opt-outs not all
-countries have participated in every vote.Interactive plot
-
-ggplot2
and ggiraph
. The following plot shows
-the variation in \(p_i\) where \(i\) indexes Member States.
-
# viz Council votes and weighted proportion
-iplot_votes_prop <- country_votes_prop %>%
- mutate(tooltip = str_c(country,": ", prop, ". Total number of votes: ", n_votes)) %>%
- ggplot(aes(y = reorder(country, prop), x = prop, yend = reorder(country, prop), xend = 0, color = prop)) +
- geom_vline(xintercept = c(0.25,0.5,0.75), color = "grey90", lty = 2) +
- geom_point_interactive(aes(tooltip = tooltip, data_id = country),
- show.legend = FALSE) +
- geom_segment_interactive(aes(tooltip = tooltip, data_id = country),
- show.legend = FALSE) +
- theme_minimal(base_family = "Arial") +
- theme(legend.position = "top",
- legend.justification = "left",
- legend.title = element_text(face = "italic"),
- plot.background = element_rect(fill = "white", color = "grey88"),
- axis.text = element_text(color = "grey10", size = 12),
- title = element_text(face = "bold", size = 16),
- panel.grid = element_line(color = "grey94"),
- axis.title = element_text(hjust = 1, size = 14),
- plot.subtitle = element_text(face = "italic", size = 15),
- plot.caption = element_text(face = "italic", size = 8),
- strip.text = element_text(hjust = 0, face = "bold")) +
- scale_x_continuous(expand = c(0.01,0)) +
- scale_color_gradient(low = "red", high = "navyblue") +
- labs(x = NULL,
- y = NULL,
- color = NULL,
- fill = NULL,
- title = "Legislative discontent in the Council",
- subtitle = "Weighted proportion of government votes in favour on contested legislation*",
- caption = "* Only legislation with at least one vote not in favour; abstentions (x1) and votes against (x2) are subtracted from votes in favour")
-
-# interactive plot
-girafe(ggobj = iplot_votes_prop,
- fonts = list(sans = "Arial"),
- width_svg = 12,
- height_svg = 8,
- options = list(opts_sizing(rescale = TRUE),
- opts_toolbar(saveaspng = FALSE),
- opts_tooltip(css = "background-color:gray;color:white;font-style:italic;padding:9px;border-radius:5px;font-size:15px;",
- use_fill = TRUE),
- opts_hover_inv(css = "opacity:0.1;"),
- opts_hover(css = "fill:green;"))
-)
-
-
-eurlex: Retrieve data on European Union law in
R
-
+ Source: vignettes/articles/eurlexpkg.Rmd
eurlexpkg.Rmd
The
eurlex
package
elx_curia_list()
) and
-Council votes (elx_council_votes()
) from outside Eur-Lex.
-More advanced users might be interested in downloading and
-custom-parsing XML notices with elx_download_xml()
.elx_council_votes()
, currently
+dysfunctional) from outside Eur-Lex. More advanced users might be
+interested in downloading and custom-parsing XML notices with
+elx_download_xml()
.
elx_make_query()
: Generate SPARQL queries
@@ -164,50 +172,12 @@
query_dir %>%
cat()
-#> PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
-#> PREFIX annot: <http://publications.europa.eu/ontology/annotation#>
-#> PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
-#> PREFIX dc:<http://purl.org/dc/elements/1.1/>
-#> PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>
-#> PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-#> PREFIX owl:<http://www.w3.org/2002/07/owl#>
-#> select distinct ?work ?type ?celex where{ ?work cdm:work_has_resource-type ?type. FILTER(?type=<http://publications.europa.eu/resource/authority/resource-type/DIR>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/DIR_IMPL>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/DIR_DEL>)
-#> FILTER not exists{?work cdm:work_has_resource-type <http://publications.europa.eu/resource/authority/resource-type/CORRIGENDUM>} OPTIONAL{?work cdm:resource_legal_id_celex ?celex.} FILTER not exists{?work cdm:do_not_index "true"^^<http://www.w3.org/2001/XMLSchema#boolean>}. }
elx_make_query(resource_type = "caselaw") %>%
cat()
-#> PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
-#> PREFIX annot: <http://publications.europa.eu/ontology/annotation#>
-#> PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
-#> PREFIX dc:<http://purl.org/dc/elements/1.1/>
-#> PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>
-#> PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-#> PREFIX owl:<http://www.w3.org/2002/07/owl#>
-#> select distinct ?work ?type ?celex where{ ?work cdm:work_has_resource-type ?type. FILTER(?type=<http://publications.europa.eu/resource/authority/resource-type/JUDG>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/ORDER>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/OPIN_JUR>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/THIRDPARTY_PROCEED>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/GARNISHEE_ORDER>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RULING>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/JUDG_EXTRACT>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/INFO_JUDICIAL>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/VIEW_AG>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/OPIN_AG>)
-#> FILTER not exists{?work cdm:work_has_resource-type <http://publications.europa.eu/resource/authority/resource-type/CORRIGENDUM>} OPTIONAL{?work cdm:resource_legal_id_celex ?celex.} FILTER not exists{?work cdm:do_not_index "true"^^<http://www.w3.org/2001/XMLSchema#boolean>}. }
elx_make_query(resource_type = "manual", manual_type = "SWD") %>%
- cat()
-#> PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
-#> PREFIX annot: <http://publications.europa.eu/ontology/annotation#>
-#> PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
-#> PREFIX dc:<http://purl.org/dc/elements/1.1/>
-#> PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>
-#> PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-#> PREFIX owl:<http://www.w3.org/2002/07/owl#>
-#> select distinct ?work ?type ?celex where{ ?work cdm:work_has_resource-type ?type.FILTER(?type=<http://publications.europa.eu/resource/authority/resource-type/SWD>)
-#> FILTER not exists{?work cdm:work_has_resource-type <http://publications.europa.eu/resource/authority/resource-type/CORRIGENDUM>} OPTIONAL{?work cdm:resource_legal_id_celex ?celex.} FILTER not exists{?work cdm:do_not_index "true"^^<http://www.w3.org/2001/XMLSchema#boolean>}. }
There are various ways of querying the same information in the Cellar database due to the existence of several overlapping classes and identifiers describing the same resources. The queries generated by the @@ -231,43 +201,11 @@
elx_make_query(resource_type = "directive", include_date = TRUE, include_force = TRUE) %>%
cat()
-#> PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
-#> PREFIX annot: <http://publications.europa.eu/ontology/annotation#>
-#> PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
-#> PREFIX dc:<http://purl.org/dc/elements/1.1/>
-#> PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>
-#> PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-#> PREFIX owl:<http://www.w3.org/2002/07/owl#>
-#> select distinct ?work ?type ?celex ?date ?force where{ ?work cdm:work_has_resource-type ?type. FILTER(?type=<http://publications.europa.eu/resource/authority/resource-type/DIR>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/DIR_IMPL>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/DIR_DEL>)
-#> FILTER not exists{?work cdm:work_has_resource-type <http://publications.europa.eu/resource/authority/resource-type/CORRIGENDUM>} OPTIONAL{?work cdm:resource_legal_id_celex ?celex.} OPTIONAL{?work cdm:work_date_document ?date.} OPTIONAL{?work cdm:resource_legal_in-force ?force.} FILTER not exists{?work cdm:do_not_index "true"^^<http://www.w3.org/2001/XMLSchema#boolean>}. }
# minimal query: elx_make_query(resource_type = "directive")
elx_make_query(resource_type = "recommendation", include_date = TRUE, include_lbs = TRUE) %>%
cat()
-#> PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
-#> PREFIX annot: <http://publications.europa.eu/ontology/annotation#>
-#> PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
-#> PREFIX dc:<http://purl.org/dc/elements/1.1/>
-#> PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>
-#> PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-#> PREFIX owl:<http://www.w3.org/2002/07/owl#>
-#> select distinct ?work ?type ?celex ?date ?lbs ?lbcelex ?lbsuffix where{ ?work cdm:work_has_resource-type ?type. FILTER(?type=<http://publications.europa.eu/resource/authority/resource-type/RECO>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RECO_DEC>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RECO_DIR>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RECO_OPIN>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RECO_RES>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RECO_REG>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RECO_RECO>||
-#> ?type=<http://publications.europa.eu/resource/authority/resource-type/RECO_DRAFT>)
-#> FILTER not exists{?work cdm:work_has_resource-type <http://publications.europa.eu/resource/authority/resource-type/CORRIGENDUM>} OPTIONAL{?work cdm:resource_legal_id_celex ?celex.} OPTIONAL{?work cdm:work_date_document ?date.} OPTIONAL{?work cdm:resource_legal_based_on_resource_legal ?lbs.
-#> ?lbs cdm:resource_legal_id_celex ?lbcelex.
-#> OPTIONAL{?bn owl:annotatedSource ?work.
-#> ?bn owl:annotatedProperty <http://publications.europa.eu/ontology/cdm#resource_legal_based_on_resource_legal>.
-#> ?bn owl:annotatedTarget ?lbs.
-#> ?bn annot:comment_on_legal_basis ?lbsuffix}} FILTER not exists{?work cdm:do_not_index "true"^^<http://www.w3.org/2001/XMLSchema#boolean>}. }
# minimal query: elx_make_query(resource_type = "recommendation")
You can also decide to not specify any resource types, in which case @@ -284,30 +222,7 @@
Now that we have a query, we are ready to run it.
-as_tibble(results)
-#> # A tibble: 4,449 × 3
-#> work type celex
-#> <chr> <chr> <chr>
-#> 1 469391ea-6c79-4680-84aa-c33db274e271 DIR 31979L0173
-#> 2 e8fcaf0d-443a-40ec-b778-34b7d895d334 DIR 31989L0194
-#> 3 52639f5f-ecaf-4f99-b633-e954cea5c8f3 DIR 31984L0378
-#> 4 c7560407-689b-4752-9fb0-d0624ed83a19 DIR 31966L0683
-#> # ℹ 4,445 more rows
as_tibble(results)
The function outputs a data.frame
where each column
corresponds to one of the requested variables, while the rows accumulate
observations of the resource type satisfying the query criteria.
@@ -356,16 +263,9 @@
head(results$type,5)
-#> [1] "DIR" "DIR" "DIR" "DIR" "DIR"
results %>%
- distinct(type)
-#> # A tibble: 3 × 1
-#> type
-#> <chr>
-#> 1 DIR
-#> 2 DIR_IMPL
-#> 3 DIR_DEL
The data is returned in the long format, which means that rows are recycled up to the length of the variable with the most data points. For example, if 20 directives are returned, each with two legal bases, the @@ -387,15 +287,7 @@
By default, the endpoint returns the EuroVoc concept codes rather
than the labels (keywords). The function
elx_label_eurovoc()
needs to be called to obtain a look-up
@@ -403,30 +295,13 @@
eurovoc_lookup <- elx_label_eurovoc(uri_eurovoc = rec_eurovoc$eurovoc)
-print(eurovoc_lookup)
-#> # A tibble: 9 × 2
-#> eurovoc labels
-#> <chr> <chr>
-#> 1 http://eurovoc.europa.eu/1085 France
-#> 2 http://eurovoc.europa.eu/1442 food inspection
-#> 3 http://eurovoc.europa.eu/1076 form
-#> 4 http://eurovoc.europa.eu/1318 Germany
-#> # ℹ 5 more rows
+print(eurovoc_lookup)
The results include labels only for unique identifiers, but with
dplyr::left_join()
it is straightforward to append the
labels to the entire dataset.
rec_eurovoc %>%
- left_join(eurovoc_lookup)
-#> Joining with `by = join_by(eurovoc)`
-#> # A tibble: 10 × 5
-#> work type celex eurovoc labels
-#> <chr> <chr> <chr> <chr> <chr>
-#> 1 e46f89c5-2db2-4157-9f24-644b32b64070 RECO 32012H0090 http://eurovoc.e… consu…
-#> 2 120a2b97-ef75-494e-ad48-1fa46932e26a RECO 31962H0816 http://eurovoc.e… welfa…
-#> 3 123da027-350c-4c61-bc40-8e46869b89cb RECO 31974H0435 http://eurovoc.e… France
-#> 4 8a363aee-7d70-4d41-b8df-3bf487320572 RECO 31996H0592 http://eurovoc.e… form
-#> # ℹ 6 more rows
As elsewhere in the API, we can tap into the multilingual nature of EU documents also when it comes to the EuroVoc keywords. Moreover, most concepts in the thesaurus are associated with alternative labels; these @@ -438,16 +313,7 @@
Note that text requests are by far the most time-intensive; requesting the full text for thousands of documents is liable to extend the run-time into hours. Texts are retrieved from html by priority, but @@ -519,7 +377,6 @@
Directives become naturally outdated with time. It might be all the more interesting to see which older acts are thus still surviving.
@@ -531,7 +388,6 @@Applicationtheme(axis.text.y = element_blank(), axis.line.y = element_blank(), axis.ticks.y = element_blank())
We want to know a bit more about some directives from the early 1970s that are still in force today. Their titles could give us a clue.
@@ -543,15 +399,7 @@Application"title")) %>% as_tibble() -print(dirs_1970_title) -#> # A tibble: 10 × 6 -#> work type celex date force title -#> <chr> <chr> <chr> <chr> <chr> <chr> -#> 1 http://publications.europa.eu/resource/cellar/c… DIR 3197… 1972… true Coun… -#> 2 http://publications.europa.eu/resource/cellar/f… DIR 3197… 1972… true Coun… -#> 3 http://publications.europa.eu/resource/cellar/a… DIR 3197… 1971… true Coun… -#> 4 http://publications.europa.eu/resource/cellar/c… DIR 3197… 1970… true Coun… -#> # ℹ 6 more rows
I will use the tidytext
package to get a quick idea of
what the legislation is about.
@@ -566,7 +414,6 @@Applicationfilter(!grepl("\\d", word)) %>% bind_tf_idf(word, celex, n) %>% with(wordcloud(word, tf_idf, max.words = 40))
I use term-frequency inverse-document frequency (tf-idf) to weight the importance of the words in the wordcloud. If we used pure frequencies, the wordcloud would largely consist of words conveying diff --git a/docs/articles/index.html b/docs/articles/index.html index 057556c..bfefc63 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -17,7 +17,7 @@
@@ -44,7 +44,13 @@vignettes/sparql-queries.Rmd
sparql-queries.Rmd
eurlex
package
The package also contains largely self-explanatory functions for
retrieving data on EU court cases (elx_curia_list()
) and
-Council votes (elx_council_votes()
) from outside Eur-Lex.
-More advanced users might be interested in downloading and
-custom-parsing XML notices with elx_download_xml()
.
elx_council_votes()
, currently
+dysfunctional) from outside Eur-Lex. More advanced users might be
+interested in downloading and custom-parsing XML notices with
+elx_download_xml()
.
elx_make_query()
: Generate SPARQL queries
diff --git a/docs/authors.html b/docs/authors.html
index 955cc61..ddb334f 100644
--- a/docs/authors.html
+++ b/docs/authors.html
@@ -17,7 +17,7 @@
inst/CITATION
Michal Ovádek (2021) Facilitating access to data on European Union laws, Political Research Exchange, 3:1, DOI: 10.1080/2474736X.2020.1870150
+Michal Ovádek (2021) Facilitating access to data on European Union laws, Political Research Exchange, 3:1, DOI: 10.1080/2474736X.2020.1870150
+@article{ovadek2021facilitating,
+ author = {Ovádek, Michal},
+ title = {Facilitating access to data on European Union laws},
+ year = {2021},
+ journal = {Political Research Exchange},
+ volume = {3},
+ number = {1},
+ pages = {Article No. 1870150},
+ url = {https://doi.org/10.1080/2474736X.2020.1870150}
+}
elx_run_query()
to execute the pre-made or any other manually input query; and elx_fetch_data()
to fire GET requests for certain metadata to the REST API.
The function elx_make_query
takes as its first argument the type of resource to be retrieved (such as “directive” or “any”) from the semantic database that powers Eur-Lex (and other publications) called Cellar. If you are familiar with SPARQL, you can always specify your own queries and execute them with elx_run_query()
.
elx_run_query()
executes SPARQL queries on a pre-specified endpoint of the EU Publication Office. It outputs a data.frame
where each column corresponds to one of the requested variables, while the rows accumulate observations of the resource type satisfying the query criteria. Obviously, the more data is to be returned, the longer the execution time, varying from a few seconds to several hours, depending also on your connection. The first column always contains the unique URI of a “work” (usually legislative act or court judgment) which identifies each resource in Cellar. Several human-readable identifiers are normally associated with each “work” but the most useful one tends to be CELEX, retrieved by default.
+ diff --git a/docs/news/index.html b/docs/news/index.html index 2dfa544..b551cc9 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -17,7 +17,7 @@
NEWS.md
elx_council_votes()
and elx_curia_list()
now fail gracefullyelx_council_votes()
and elx_curia_list()
now fail gracefullyelx_council_votes()
made fully operationalelx_council_votes()
made fully operational
# \donttest{
elx_curia_list(data = "cst_all", parse = FALSE)
-#> Error in rvest::html_text(hrefs, "href"): `trim` must be `TRUE` or `FALSE`, not the string "href".
+#> # A tibble: 1,760 × 3
+#> case_id case_id_celex case_info
+#> <chr> <chr> <chr>
+#> 1 F-1/05 * NA Judgment of 26 October 2006, Landgren / ETF (F-1/05…
+#> 2 F-1/05 NA Order of 22 May 2007, Landgren / ETF (F-1/05, ECR-S…
+#> 3 F-1/05 INT NA Order of 13 July 2007, Landgren / ETF (F-1/05 INT, …
+#> 4 F-1/05 NA Order of 9 November 2010, Landgren / ETF (F-1/05, u…
+#> 5 F-2/05 NA Removed from the register on 18 June 2008, Kröppeli…
+#> 6 F-3/05 NA Order of 15 May 2006, Schmit / Commission (F-3/05, …
+#> 7 F-4/05 NA Removed from the register on 18 June 2008, Huober /…
+#> 8 F-5/05 * NA Judgment of 28 April 2009, Violetti and others / Co…
+#> 9 F-6/05 NA Removed from the register on 18 June 2008, Kröppeli…
+#> 10 F-7/05 NA Schmit / Commission (F-7/05) , see Case F-5/05
+#> # ℹ 1,750 more rows
# }
Retrieve Council votes on EU acts
Scrape list of court cases from Curia