Full Code of CaliOpen/Caliopen for AI

master 7ae023582358 cached
2425 files
10.9 MB
3.0M tokens
4599 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (12,044K chars total). Download the full file to get everything.
Repository: CaliOpen/Caliopen
Branch: master
Commit: 7ae023582358
Files: 2425
Total size: 10.9 MB

Directory structure:
gitextract_it3wvh4t/

├── .drone.yml
├── .git-crypt/
│   ├── .gitattributes
│   └── keys/
│       └── default/
│           └── 0/
│               ├── 3A1172187EF7406FCBCECFA60E68C4F85D04D8FC.gpg
│               ├── A08EA82ED095FCD8575AB3742DC613553716A878.gpg
│               ├── E6711893CE02FDEEA5B1F79FF3D83146E5111526.gpg
│               └── EA440246DFB690B5B1FB4032CE011C4615DB040A.gpg
├── .gitattributes
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── devtools/
│   ├── ES_queries/
│   │   └── Recipient_suggest.json
│   ├── Vagrantfile
│   ├── api-mock/
│   │   ├── README.md
│   │   ├── all.fixture.js
│   │   ├── authentications/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── bin/
│   │   │   └── start
│   │   ├── collection-middleware/
│   │   │   └── index.js
│   │   ├── contacts/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── devices/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── discussions/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── local_identities/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── me/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── messages/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── notifications/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── oauth-mock/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── package.json
│   │   ├── participants/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── providers/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── remote_identities/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── search/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── settings/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   └── tags/
│   │       ├── data.json
│   │       └── index.js
│   ├── clean-dev-storage.sh
│   ├── conf/
│   │   └── proxy-api.conf
│   ├── docker-compose.staging.yml
│   ├── docker-compose.yml
│   ├── drone/
│   │   ├── build_images.sh
│   │   ├── files_changed.sh
│   │   ├── get_go_dependencies.sh
│   │   ├── get_py_dependencies.sh
│   │   ├── test_front.sh
│   │   ├── test_go.sh
│   │   └── test_py.sh
│   ├── extract/
│   │   └── email_graph.py
│   ├── fixtures/
│   │   ├── mbox/
│   │   │   ├── dev@caliopen.local/
│   │   │   │   ├── 1460463561.5266_1.argentina:2,
│   │   │   │   ├── 1460463561.5266_11.argentina:2,
│   │   │   │   ├── 1460463561.5266_13.argentina:2,
│   │   │   │   ├── 1460463561.5266_15.argentina:2,
│   │   │   │   ├── 1460463561.5266_17.argentina:2,
│   │   │   │   ├── 1460463561.5266_19.argentina:2,
│   │   │   │   ├── 1460463561.5266_21.argentina:2,
│   │   │   │   ├── 1460463561.5266_23.argentina:2,
│   │   │   │   ├── 1460463561.5266_25.argentina:2,
│   │   │   │   ├── 1460463561.5266_27.argentina:2,
│   │   │   │   ├── 1460463561.5266_29.argentina:2,
│   │   │   │   ├── 1460463561.5266_3.argentina:2,
│   │   │   │   ├── 1460463561.5266_31.argentina:2,
│   │   │   │   ├── 1460463561.5266_33.argentina:2,
│   │   │   │   ├── 1460463561.5266_35.argentina:2,
│   │   │   │   ├── 1460463561.5266_37.argentina:2,
│   │   │   │   ├── 1460463561.5266_39.argentina:2,
│   │   │   │   ├── 1460463561.5266_41.argentina:2,
│   │   │   │   ├── 1460463561.5266_43.argentina:2,
│   │   │   │   ├── 1460463561.5266_45.argentina:2,
│   │   │   │   ├── 1460463561.5266_47.argentina:2,
│   │   │   │   ├── 1460463561.5266_49.argentina:2,
│   │   │   │   ├── 1460463561.5266_5.argentina:2,
│   │   │   │   ├── 1460463561.5266_51.argentina:2,
│   │   │   │   ├── 1460463561.5266_53.argentina:2,
│   │   │   │   ├── 1460463561.5266_55.argentina:2,
│   │   │   │   ├── 1460463561.5266_57.argentina:2,
│   │   │   │   ├── 1460463561.5266_59.argentina:2,
│   │   │   │   ├── 1460463561.5266_61.argentina:2,
│   │   │   │   ├── 1460463561.5266_63.argentina:2,
│   │   │   │   ├── 1460463561.5266_7.argentina:2,
│   │   │   │   ├── 1460463561.5266_9.argentina:2,
│   │   │   │   ├── 1460463562.5266_101.argentina:2,
│   │   │   │   ├── 1460463562.5266_103.argentina:2,
│   │   │   │   ├── 1460463562.5266_105.argentina:2,
│   │   │   │   ├── 1460463562.5266_107.argentina:2,
│   │   │   │   ├── 1460463562.5266_109.argentina:2,
│   │   │   │   ├── 1460463562.5266_111.argentina:2,
│   │   │   │   ├── 1460463562.5266_113.argentina:2,
│   │   │   │   ├── 1460463562.5266_115.argentina:2,
│   │   │   │   ├── 1460463562.5266_117.argentina:2,
│   │   │   │   ├── 1460463562.5266_119.argentina:2,
│   │   │   │   ├── 1460463562.5266_121.argentina:2,
│   │   │   │   ├── 1460463562.5266_123.argentina:2,
│   │   │   │   ├── 1460463562.5266_125.argentina:2,
│   │   │   │   ├── 1460463562.5266_127.argentina:2,
│   │   │   │   ├── 1460463562.5266_129.argentina:2,
│   │   │   │   ├── 1460463562.5266_131.argentina:2,
│   │   │   │   ├── 1460463562.5266_133.argentina:2,
│   │   │   │   ├── 1460463562.5266_135.argentina:2,
│   │   │   │   ├── 1460463562.5266_137.argentina:2,
│   │   │   │   ├── 1460463562.5266_139.argentina:2,
│   │   │   │   ├── 1460463562.5266_141.argentina:2,
│   │   │   │   ├── 1460463562.5266_143.argentina:2,
│   │   │   │   ├── 1460463562.5266_145.argentina:2,
│   │   │   │   ├── 1460463562.5266_147.argentina:2,
│   │   │   │   ├── 1460463562.5266_149.argentina:2,
│   │   │   │   ├── 1460463562.5266_151.argentina:2,
│   │   │   │   ├── 1460463562.5266_153.argentina:2,
│   │   │   │   ├── 1460463562.5266_65.argentina:2,
│   │   │   │   ├── 1460463562.5266_67.argentina:2,
│   │   │   │   ├── 1460463562.5266_69.argentina:2,
│   │   │   │   ├── 1460463562.5266_71.argentina:2,
│   │   │   │   ├── 1460463562.5266_73.argentina:2,
│   │   │   │   ├── 1460463562.5266_75.argentina:2,
│   │   │   │   ├── 1460463562.5266_77.argentina:2,
│   │   │   │   ├── 1460463562.5266_79.argentina:2,
│   │   │   │   ├── 1460463562.5266_81.argentina:2,
│   │   │   │   ├── 1460463562.5266_83.argentina:2,
│   │   │   │   ├── 1460463562.5266_85.argentina:2,
│   │   │   │   ├── 1460463562.5266_87.argentina:2,
│   │   │   │   ├── 1460463562.5266_89.argentina:2,
│   │   │   │   ├── 1460463562.5266_91.argentina:2,
│   │   │   │   ├── 1460463562.5266_93.argentina:2,
│   │   │   │   ├── 1460463562.5266_95.argentina:2,
│   │   │   │   ├── 1460463562.5266_97.argentina:2,
│   │   │   │   ├── 1460463562.5266_99.argentina:2,
│   │   │   │   ├── 1460463563.5266_155.argentina:2,
│   │   │   │   ├── 1460463563.5266_157.argentina:2,
│   │   │   │   ├── 1460463563.5266_159.argentina:2,
│   │   │   │   ├── 1460463563.5266_161.argentina:2,
│   │   │   │   ├── 1460463563.5266_163.argentina:2,
│   │   │   │   ├── 1460463563.5266_165.argentina:2,
│   │   │   │   ├── 1460463563.5266_167.argentina:2,
│   │   │   │   ├── 1460463563.5266_169.argentina:2,
│   │   │   │   ├── 1460463563.5266_171.argentina:2,
│   │   │   │   ├── 1460463563.5266_173.argentina:2,
│   │   │   │   ├── 1460463563.5266_175.argentina:2,
│   │   │   │   ├── 1460463563.5266_177.argentina:2,
│   │   │   │   ├── 1460463563.5266_179.argentina:2,
│   │   │   │   ├── 1460463563.5266_181.argentina:2,
│   │   │   │   ├── 1460463563.5266_183.argentina:2,
│   │   │   │   ├── 1460463563.5266_185.argentina:2,
│   │   │   │   ├── 1460463563.5266_187.argentina:2,
│   │   │   │   ├── 1460463563.5266_189.argentina:2,
│   │   │   │   ├── 1460463563.5266_193.argentina:2,
│   │   │   │   ├── 1460463563.5266_195.argentina:2,
│   │   │   │   ├── 1460463563.5266_197.argentina:2,
│   │   │   │   ├── 1460463563.5266_199.argentina:2,
│   │   │   │   ├── 1460463563.5266_201.argentina:2,
│   │   │   │   ├── 1460463563.5266_205.argentina:2,
│   │   │   │   ├── 1460463563.5266_207.argentina:2,
│   │   │   │   ├── 1460463563.5266_209.argentina:2,
│   │   │   │   ├── 1460463563.5266_211.argentina:2,
│   │   │   │   ├── 1460463563.5266_213.argentina:2,
│   │   │   │   ├── 1460463563.5266_215.argentina:2,
│   │   │   │   ├── 1460463563.5266_217.argentina:2,
│   │   │   │   ├── 1460463563.5266_219.argentina:2,
│   │   │   │   ├── 1460463563.5266_221.argentina:2,
│   │   │   │   ├── 1460463563.5266_223.argentina:2,
│   │   │   │   ├── 1460463563.5266_225.argentina:2,
│   │   │   │   ├── 1460463563.5266_227.argentina:2,
│   │   │   │   ├── 1460463563.5266_229.argentina:2,
│   │   │   │   ├── 1460463563.5266_231.argentina:2,
│   │   │   │   ├── 1460463563.5266_233.argentina:2,
│   │   │   │   ├── 1460463563.5266_235.argentina:2,
│   │   │   │   ├── 1460463563.5266_237.argentina:2,
│   │   │   │   ├── 1460463563.5266_239.argentina:2,
│   │   │   │   ├── 1460463563.5266_241.argentina:2,
│   │   │   │   ├── 1460463563.5266_243.argentina:2,
│   │   │   │   ├── 1460463564.5266_245.argentina:2,
│   │   │   │   ├── 1460463564.5266_247.argentina:2,
│   │   │   │   ├── 1460463564.5266_249.argentina:2,
│   │   │   │   ├── 1460463564.5266_253.argentina:2,
│   │   │   │   ├── 1460463564.5266_255.argentina:2,
│   │   │   │   ├── 1460463564.5266_257.argentina:2,
│   │   │   │   ├── 1460463564.5266_259.argentina:2,
│   │   │   │   ├── 1460463564.5266_261.argentina:2,
│   │   │   │   ├── 1460463564.5266_263.argentina:2,
│   │   │   │   ├── 1460463564.5266_265.argentina:2,
│   │   │   │   ├── 1460463564.5266_267.argentina:2,
│   │   │   │   ├── 1460463564.5266_269.argentina:2,
│   │   │   │   ├── 1460463564.5266_271.argentina:2,
│   │   │   │   ├── 1460463564.5266_273.argentina:2,
│   │   │   │   ├── 1460463564.5266_275.argentina:2,
│   │   │   │   ├── 1460463564.5266_277.argentina:2,
│   │   │   │   ├── 1460463564.5266_279.argentina:2,
│   │   │   │   ├── 1460463564.5266_281.argentina:2,
│   │   │   │   ├── 1460463564.5266_283.argentina:2,
│   │   │   │   ├── 1460463564.5266_285.argentina:2,
│   │   │   │   ├── 1460463564.5266_287.argentina:2,
│   │   │   │   ├── 1460463564.5266_289.argentina:2,
│   │   │   │   ├── 1460463564.5266_291.argentina:2,
│   │   │   │   ├── 1460463564.5266_293.argentina:2,
│   │   │   │   ├── 1460463564.5266_295.argentina:2,
│   │   │   │   ├── 1460463564.5266_297.argentina:2,
│   │   │   │   ├── 1460463564.5266_299.argentina:2,
│   │   │   │   ├── 1460463564.5266_301.argentina:2,
│   │   │   │   ├── 1460463564.5266_303.argentina:2,
│   │   │   │   ├── 1460463564.5266_305.argentina:2,
│   │   │   │   ├── 1460463564.5266_307.argentina:2,
│   │   │   │   ├── 1460463564.5266_309.argentina:2,
│   │   │   │   ├── 1460463564.5266_311.argentina:2,
│   │   │   │   ├── 1460463564.5266_313.argentina:2,
│   │   │   │   ├── 1460463564.5266_315.argentina:2,
│   │   │   │   ├── 1460463564.5266_317.argentina:2,
│   │   │   │   ├── 1460463564.5266_319.argentina:2,
│   │   │   │   ├── 1460463564.5266_321.argentina:2,
│   │   │   │   ├── 1460463564.5266_323.argentina:2,
│   │   │   │   ├── 1460463564.5266_325.argentina:2,
│   │   │   │   ├── 1460463564.5266_327.argentina:2,
│   │   │   │   ├── 1460463564.5266_329.argentina:2,
│   │   │   │   ├── 1460463564.5266_331.argentina:2,
│   │   │   │   ├── 1460463564.5266_333.argentina:2,
│   │   │   │   ├── 1460463564.5266_335.argentina:2,
│   │   │   │   ├── 1460463564.5266_337.argentina:2,
│   │   │   │   ├── 1460463564.5266_339.argentina:2,
│   │   │   │   ├── 1460463564.5266_341.argentina:2,
│   │   │   │   ├── 1460463564.5266_343.argentina:2,
│   │   │   │   ├── 1460463565.5266_345.argentina:2,
│   │   │   │   ├── 1460463565.5266_347.argentina:2,
│   │   │   │   ├── 1460463565.5266_349.argentina:2,
│   │   │   │   ├── 1460463565.5266_351.argentina:2,
│   │   │   │   ├── 1460463565.5266_353.argentina:2,
│   │   │   │   ├── 1460463565.5266_355.argentina:2,
│   │   │   │   ├── 1460463565.5266_357.argentina:2,
│   │   │   │   ├── 1460463565.5266_359.argentina:2,
│   │   │   │   ├── 1460463565.5266_361.argentina:2,
│   │   │   │   ├── 1460463565.5266_363.argentina:2,
│   │   │   │   ├── 1460463565.5266_365.argentina:2,
│   │   │   │   ├── 1460463565.5266_367.argentina:2,
│   │   │   │   ├── 1460463565.5266_369.argentina:2,
│   │   │   │   ├── 1460463565.5266_371.argentina:2,
│   │   │   │   ├── 1460463565.5266_373.argentina:2,
│   │   │   │   ├── 1460463565.5266_375.argentina:2,
│   │   │   │   ├── 1460463565.5266_377.argentina:2,
│   │   │   │   ├── 1460463565.5266_379.argentina:2,
│   │   │   │   ├── 1460463565.5266_381.argentina:2,
│   │   │   │   ├── 1460463565.5266_383.argentina:2,
│   │   │   │   ├── 1460463565.5266_385.argentina:2,
│   │   │   │   ├── 1460463565.5266_387.argentina:2,
│   │   │   │   ├── 1460463565.5266_389.argentina:2,
│   │   │   │   ├── 1460463565.5266_391.argentina:2,
│   │   │   │   ├── 1460463565.5266_393.argentina:2,
│   │   │   │   ├── 1460463565.5266_395.argentina:2,
│   │   │   │   ├── 1460463565.5266_397.argentina:2,
│   │   │   │   ├── 1460463565.5266_399.argentina:2,
│   │   │   │   ├── 1460463565.5266_401.argentina:2,
│   │   │   │   ├── 1460463565.5266_403.argentina:2,
│   │   │   │   ├── 1460463565.5266_405.argentina:2,
│   │   │   │   ├── 1460463565.5266_407.argentina:2,
│   │   │   │   ├── 1460463565.5266_409.argentina:2,
│   │   │   │   ├── 1460463565.5266_411.argentina:2,
│   │   │   │   ├── 1460463565.5266_413.argentina:2,
│   │   │   │   ├── 1460463565.5266_415.argentina:2,
│   │   │   │   ├── 1460463565.5266_417.argentina:2,
│   │   │   │   ├── 1460463565.5266_419.argentina:2,
│   │   │   │   ├── 1460463565.5266_421.argentina:2,
│   │   │   │   ├── 1460463565.5266_423.argentina:2,
│   │   │   │   ├── 1460463565.5266_425.argentina:2,
│   │   │   │   ├── 1460463565.5266_427.argentina:2,
│   │   │   │   ├── 1460463565.5266_429.argentina:2,
│   │   │   │   ├── 1460463565.5266_431.argentina:2,
│   │   │   │   ├── 1460463565.5266_433.argentina:2,
│   │   │   │   ├── 1460463565.5266_435.argentina:2,
│   │   │   │   ├── 1460463566.5266_437.argentina:2,
│   │   │   │   ├── 1460463566.5266_439.argentina:2,
│   │   │   │   ├── 1460463566.5266_441.argentina:2,
│   │   │   │   ├── 1460463566.5266_443.argentina:2,
│   │   │   │   ├── 1460463566.5266_445.argentina:2,
│   │   │   │   ├── 1460463566.5266_447.argentina:2,
│   │   │   │   ├── 1460463566.5266_449.argentina:2,
│   │   │   │   ├── 1460463566.5266_451.argentina:2,
│   │   │   │   ├── 1460463566.5266_453.argentina:2,
│   │   │   │   ├── 1460463566.5266_455.argentina:2,
│   │   │   │   ├── 1460463566.5266_457.argentina:2,
│   │   │   │   ├── 1460463566.5266_459.argentina:2,
│   │   │   │   ├── 1460463566.5266_461.argentina:2,
│   │   │   │   ├── 1460463566.5266_463.argentina:2,
│   │   │   │   ├── 1460463566.5266_465.argentina:2,
│   │   │   │   ├── 1460463566.5266_467.argentina:2,
│   │   │   │   ├── 1460463566.5266_469.argentina:2,
│   │   │   │   ├── 1460463566.5266_471.argentina:2,
│   │   │   │   ├── 1460463566.5266_473.argentina:2,
│   │   │   │   ├── 1460463566.5266_475.argentina:2,
│   │   │   │   ├── 1460463567.5266_477.argentina:2,
│   │   │   │   ├── 1460463567.5266_483.argentina:2,
│   │   │   │   ├── 1460463567.5266_485.argentina:2,
│   │   │   │   ├── 1460463567.5266_487.argentina:2,
│   │   │   │   ├── 1460463567.5266_489.argentina:2,
│   │   │   │   ├── 1460463567.5266_491.argentina:2,
│   │   │   │   ├── 1460463567.5266_493.argentina:2,
│   │   │   │   ├── 1460463567.5266_495.argentina:2,
│   │   │   │   ├── 1460463567.5266_497.argentina:2,
│   │   │   │   ├── 1460463567.5266_499.argentina:2,
│   │   │   │   ├── 1460463567.5266_503.argentina:2,
│   │   │   │   ├── 1460463567.5266_505.argentina:2,
│   │   │   │   ├── 1460463567.5266_507.argentina:2,
│   │   │   │   ├── 1460463567.5266_509.argentina:2,
│   │   │   │   ├── 1460463567.5266_511.argentina:2,
│   │   │   │   ├── 1460463567.5266_513.argentina:2,
│   │   │   │   ├── 1460463567.5266_515.argentina:2,
│   │   │   │   ├── 1460463567.5266_517.argentina:2,
│   │   │   │   ├── 1460463567.5266_519.argentina:2,
│   │   │   │   ├── 1460463567.5266_521.argentina:2,
│   │   │   │   ├── 1460463567.5266_525.argentina:2,
│   │   │   │   ├── 1460463567.5266_527.argentina:2,
│   │   │   │   ├── 1460463567.5266_529.argentina:2,
│   │   │   │   ├── 1460463567.5266_531.argentina:2,
│   │   │   │   ├── 1460463568.5266_533.argentina:2,
│   │   │   │   ├── 1460463568.5266_535.argentina:2,
│   │   │   │   ├── 1460463568.5266_537.argentina:2,
│   │   │   │   ├── 1460463568.5266_539.argentina:2,
│   │   │   │   ├── 1460463568.5266_541.argentina:2,
│   │   │   │   ├── 1460463568.5266_543.argentina:2,
│   │   │   │   ├── 1460463568.5266_545.argentina:2,
│   │   │   │   ├── 1460463568.5266_547.argentina:2,
│   │   │   │   ├── 1460463568.5266_549.argentina:2,
│   │   │   │   ├── 1460463568.5266_551.argentina:2,
│   │   │   │   ├── 1460463568.5266_553.argentina:2,
│   │   │   │   ├── 1460463568.5266_555.argentina:2,
│   │   │   │   ├── 1460463568.5266_557.argentina:2,
│   │   │   │   ├── 1460463568.5266_559.argentina:2,
│   │   │   │   ├── 1460463568.5266_561.argentina:2,
│   │   │   │   ├── 1460463568.5266_563.argentina:2,
│   │   │   │   ├── 1460463568.5266_565.argentina:2,
│   │   │   │   ├── 1460463568.5266_567.argentina:2,
│   │   │   │   ├── 1460463568.5266_569.argentina:2,
│   │   │   │   ├── 1460463568.5266_571.argentina:2,
│   │   │   │   ├── 1460463568.5266_573.argentina:2,
│   │   │   │   ├── 1460463568.5266_575.argentina:2,
│   │   │   │   ├── 1460463568.5266_577.argentina:2,
│   │   │   │   ├── 1460463568.5266_579.argentina:2,
│   │   │   │   ├── 1460463568.5266_581.argentina:2,
│   │   │   │   ├── 1460463568.5266_583.argentina:2,
│   │   │   │   ├── 1460463568.5266_585.argentina:2,
│   │   │   │   ├── 1460463568.5266_587.argentina:2,
│   │   │   │   ├── 1460463568.5266_589.argentina:2,
│   │   │   │   ├── 1460463568.5266_591.argentina:2,
│   │   │   │   ├── 1460463568.5266_593.argentina:2,
│   │   │   │   ├── 1460463568.5266_595.argentina:2,
│   │   │   │   ├── 1460463568.5266_597.argentina:2,
│   │   │   │   ├── 1460463568.5266_599.argentina:2,
│   │   │   │   ├── 1460463568.5266_601.argentina:2,
│   │   │   │   ├── 1460463568.5266_603.argentina:2,
│   │   │   │   ├── 1460463568.5266_605.argentina:2,
│   │   │   │   ├── 1460463568.5266_607.argentina:2,
│   │   │   │   ├── 1460463568.5266_609.argentina:2,
│   │   │   │   ├── 1460463568.5266_611.argentina:2,
│   │   │   │   ├── 1460463568.5266_613.argentina:2,
│   │   │   │   ├── 1460463568.5266_615.argentina:2,
│   │   │   │   ├── 1460463568.5266_617.argentina:2,
│   │   │   │   ├── 1460463569.5266_619.argentina:2,
│   │   │   │   ├── 1460463569.5266_621.argentina:2,
│   │   │   │   ├── 1460463569.5266_623.argentina:2,
│   │   │   │   ├── 1460463569.5266_625.argentina:2,
│   │   │   │   ├── 1460463569.5266_627.argentina:2,
│   │   │   │   ├── 1460463569.5266_629.argentina:2,
│   │   │   │   ├── 1460463569.5266_631.argentina:2,
│   │   │   │   ├── 1460463569.5266_633.argentina:2,
│   │   │   │   ├── 1460463569.5266_635.argentina:2,
│   │   │   │   ├── 1460463569.5266_637.argentina:2,
│   │   │   │   ├── 1460463569.5266_639.argentina:2,
│   │   │   │   ├── 1460463569.5266_641.argentina:2,
│   │   │   │   ├── 1460463569.5266_643.argentina:2,
│   │   │   │   ├── 1460463569.5266_645.argentina:2,
│   │   │   │   ├── 1460463569.5266_647.argentina:2,
│   │   │   │   ├── 1460463569.5266_649.argentina:2,
│   │   │   │   ├── 1460463569.5266_651.argentina:2,
│   │   │   │   ├── 1460463569.5266_653.argentina:2,
│   │   │   │   ├── 1460463569.5266_655.argentina:2,
│   │   │   │   ├── 1460463569.5266_657.argentina:2,
│   │   │   │   ├── 1460463569.5266_659.argentina:2,
│   │   │   │   ├── 1460463569.5266_661.argentina:2,
│   │   │   │   ├── 1460463569.5266_663.argentina:2,
│   │   │   │   ├── 1460463569.5266_665.argentina:2,
│   │   │   │   ├── 1460463569.5266_667.argentina:2,
│   │   │   │   ├── 1460463569.5266_669.argentina:2,
│   │   │   │   ├── 1460463569.5266_671.argentina:2,
│   │   │   │   ├── 1460463569.5266_673.argentina:2,
│   │   │   │   ├── 1460463569.5266_675.argentina:2,
│   │   │   │   ├── 1460463569.5266_677.argentina:2,
│   │   │   │   ├── 1460463569.5266_679.argentina:2,
│   │   │   │   ├── 1460463569.5266_681.argentina:2,
│   │   │   │   ├── 1460463569.5266_683.argentina:2,
│   │   │   │   ├── 1460463569.5266_685.argentina:2,
│   │   │   │   ├── 1460463569.5266_687.argentina:2,
│   │   │   │   ├── 1460463569.5266_689.argentina:2,
│   │   │   │   ├── 1460463569.5266_691.argentina:2,
│   │   │   │   ├── 1460463569.5266_693.argentina:2,
│   │   │   │   ├── 1460463569.5266_695.argentina:2,
│   │   │   │   ├── 1460463569.5266_697.argentina:2,
│   │   │   │   ├── 1460463569.5266_699.argentina:2,
│   │   │   │   ├── 1460463569.5266_701.argentina:2,
│   │   │   │   ├── 1460463569.5266_703.argentina:2,
│   │   │   │   ├── 1460463569.5266_705.argentina:2,
│   │   │   │   ├── 1460463570.5266_707.argentina:2,
│   │   │   │   ├── 1460463570.5266_709.argentina:2,
│   │   │   │   ├── 1460463570.5266_711.argentina:2,
│   │   │   │   ├── 1460463570.5266_713.argentina:2,
│   │   │   │   ├── 1460463570.5266_715.argentina:2,
│   │   │   │   ├── 1460463570.5266_717.argentina:2,
│   │   │   │   ├── 1460463570.5266_719.argentina:2,
│   │   │   │   ├── 1460463570.5266_721.argentina:2,
│   │   │   │   ├── 1460463570.5266_723.argentina:2,
│   │   │   │   ├── 1460463570.5266_725.argentina:2,
│   │   │   │   ├── 1460463570.5266_727.argentina:2,
│   │   │   │   ├── 1460463570.5266_729.argentina:2,
│   │   │   │   ├── 1460463570.5266_731.argentina:2,
│   │   │   │   ├── 1460463570.5266_733.argentina:2,
│   │   │   │   ├── 1460463570.5266_735.argentina:2,
│   │   │   │   ├── 1460463570.5266_737.argentina:2,
│   │   │   │   ├── 1460463570.5266_739.argentina:2,
│   │   │   │   ├── 1460463570.5266_741.argentina:2,
│   │   │   │   ├── 1460463570.5266_743.argentina:2,
│   │   │   │   ├── 1460463570.5266_745.argentina:2,
│   │   │   │   ├── 1460463570.5266_747.argentina:2,
│   │   │   │   ├── 1460463570.5266_749.argentina:2,
│   │   │   │   ├── 1460463570.5266_751.argentina:2,
│   │   │   │   ├── 1460463570.5266_753.argentina:2,
│   │   │   │   ├── 1460463570.5266_755.argentina:2,
│   │   │   │   ├── 1460463570.5266_757.argentina:2,
│   │   │   │   ├── 1460463570.5266_759.argentina:2,
│   │   │   │   ├── 1460463570.5266_761.argentina:2,
│   │   │   │   ├── 1460463570.5266_763.argentina:2,
│   │   │   │   ├── 1460463570.5266_765.argentina:2,
│   │   │   │   ├── 1460463570.5266_767.argentina:2,
│   │   │   │   ├── 1460463570.5266_769.argentina:2,
│   │   │   │   ├── 1460463570.5266_771.argentina:2,
│   │   │   │   ├── 1460463570.5266_773.argentina:2,
│   │   │   │   ├── 1460463570.5266_775.argentina:2,
│   │   │   │   ├── 1460463570.5266_777.argentina:2,
│   │   │   │   ├── 1460463570.5266_779.argentina:2,
│   │   │   │   ├── 1460463570.5266_781.argentina:2,
│   │   │   │   ├── 1460463571.5266_783.argentina:2,
│   │   │   │   ├── 1460463571.5266_785.argentina:2,
│   │   │   │   ├── 1460463571.5266_787.argentina:2,
│   │   │   │   ├── 1460463571.5266_789.argentina:2,
│   │   │   │   ├── 1460463571.5266_791.argentina:2,
│   │   │   │   ├── 1460463571.5266_793.argentina:2,
│   │   │   │   ├── 1460463571.5266_795.argentina:2,
│   │   │   │   ├── 1460463571.5266_797.argentina:2,
│   │   │   │   ├── 1460463571.5266_799.argentina:2,
│   │   │   │   ├── 1460463571.5266_801.argentina:2,
│   │   │   │   ├── Re: [Caliopdev] CR réunion du 12_12_2014 - David Epely <dey@protonmail.ch> - 2014-12-13 1352.eml
│   │   │   │   ├── Re: [Caliopdev] Compte rendu reunion 21 Novembre - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-22 1046.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re:  matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-26 1605.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re:  matrice de choix framework JS - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-26 2346.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re:  matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-28 1701.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alban Crommer <alban@albancrommer.com> - 2014-11-27 1007.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alban Crommer <alban@albancrommer.com> - 2014-11-28 1625.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alexis <alexis@gandi.net> - 2014-11-28 1518.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alexis <alexis@gandi.net> - 2014-11-28 1748.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-28 1112.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-28 1724.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-11-27 0132.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Vincent MINEAUD <vincent@gandi.net> - 2014-11-28 1600.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - joseph@cozycloud.cc - 2014-11-27 1120.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - joseph@cozycloud.cc - 2014-11-27 1228.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-27 1211.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-27 2140.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-28 1222.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-28 1609.eml
│   │   │   │   ├── Re: [Caliopdev] Nouveau screencast (brut) - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-30 1724.eml
│   │   │   │   ├── Re: [Caliopdev] Nouveau screencast (brut) - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-01 1214.eml
│   │   │   │   ├── Re: [Caliopdev] Nouveau screencast (brut) - Thomas Laurent <thomas.laurent@gandi.net> - 2014-12-01 1149.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Aymeric Barantal <mric@chamal.fr> - 2014-12-02 1510.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - David Epely <dey@protonmail.ch> - 2014-12-02 1056.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-01 2345.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-02 2319.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-02 2322.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-02 0610.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-02 1158.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - julien muetton <julien.muetton@gandi.net> - 2014-12-02 1031.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaines réunions. - Alban Crommer <alban@albancrommer.com> - 2014-12-29 1917.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaines étapes ? - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-06 2135.eml
│   │   │   │   ├── Re: [Caliopdev] [svetlana.meyer@ensc.fr: Bravo!] - Alexis <alexis@gandi.net> - 2014-11-26 1446.eml
│   │   │   │   ├── Re: [Caliopdev] framework js - David Epely <dey@protonmail.ch> - 2014-11-21 0920.eml
│   │   │   │   ├── Re: [Caliopdev] framework js - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-11-21 0059.eml
│   │   │   │   ├── [Caliopdev] CR réunion du 12_12_2014 - Thomas Laurent <thomas.laurent@gandi.net> - 2014-12-12 1701.eml
│   │   │   │   ├── [Caliopdev] Compte rendu reunion 21 Novembre - Aymeric Barantal <mric@chamal.fr> - 2014-11-21 1221.eml
│   │   │   │   ├── [Caliopdev] Fwd: Re:  matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-25 1119.eml
│   │   │   │   ├── [Caliopdev] Nouveau screencast (brut) - Aymeric Barantal <mric@chamal.fr> - 2014-11-28 1718.eml
│   │   │   │   ├── [Caliopdev] Prochaine réunion - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-01 2142.eml
│   │   │   │   ├── [Caliopdev] Prochaines réunions. - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-29 1807.eml
│   │   │   │   ├── [Caliopdev] Prochaines étapes ? - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-06 2108.eml
│   │   │   │   ├── [Caliopdev] [Coin-coin@canapin.com: Petites fautes dans la FAQ] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-24 1840.eml
│   │   │   │   ├── [Caliopdev] [benjamin@sonntag.fr: Fwd: ***UNCHECKED*** Caliopen FAQ] - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-15 1825.eml
│   │   │   │   ├── [Caliopdev] [contact+caliopen@etiennesamson.com: Intégration] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-24 1840.eml
│   │   │   │   ├── [Caliopdev] [groupeiw@gmail.com: Contacter l'équipe CaliOpen] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-25 1810.eml
│   │   │   │   ├── [Caliopdev] [svetlana.meyer@ensc.fr: Bravo!] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-26 1244.eml
│   │   │   │   ├── [Caliopdev] [svetlana.meyer@ensc.fr: Re: Bravo!] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-26 1246.eml
│   │   │   │   └── [Caliopdev] matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-24 1146.eml
│   │   │   └── test@caliopen.local/
│   │   │       ├── test_1.eml
│   │   │       ├── test_2.eml
│   │   │       └── test_3.eml
│   │   ├── messages_body/
│   │   │   ├── flat-html-body
│   │   │   ├── html-mailinglist
│   │   │   ├── html-with-inline-styles
│   │   │   └── spam-htmj-and-styles
│   │   ├── raw_emails/
│   │   │   ├── email-with-iso-8859-1-encoding
│   │   │   ├── html-in-plain-body
│   │   │   ├── html-with-inlined-image
│   │   │   ├── invalid-utf-8
│   │   │   ├── multipart-html
│   │   │   ├── multipart-signed
│   │   │   ├── multipart-with-attachment
│   │   │   ├── sample-mail.eml.txt
│   │   │   ├── signed-and-encrypted
│   │   │   ├── simple
│   │   │   ├── spam-multipart
│   │   │   ├── with-docx-attachment
│   │   │   └── with-json-attachment
│   │   ├── raw_inbound_msg.cql
│   │   ├── twitter/
│   │   │   ├── dm-multimedia.json
│   │   │   └── dm.json
│   │   └── vcard/
│   │       ├── multi.vcf
│   │       ├── rfc2425-1.vcard
│   │       ├── rfc2425-2.vcard
│   │       ├── rfc2425-3.vcard
│   │       ├── rfc2426-1.vcard
│   │       ├── rfc2426-2.vcard
│   │       ├── rfc2426-3.vcard
│   │       ├── rfc2426-4.vcard
│   │       └── rfc2426-5.vcard
│   ├── gen-swagger-spec.sh
│   ├── init.sh
│   ├── kubernetes/
│   │   ├── README.md
│   │   ├── clean-minikube.sh
│   │   ├── configs/
│   │   │   └── dns-config.yaml
│   │   ├── deploy-minikube.sh
│   │   ├── deployments/
│   │   │   ├── apiv1-deployment.yaml
│   │   │   ├── apiv2-deployment.yaml
│   │   │   ├── cassandra-deployment.yaml
│   │   │   ├── elasticsearch-deployment.yaml
│   │   │   ├── frontend-deployment.yaml
│   │   │   ├── identity-poller-deployment.yaml
│   │   │   ├── imap-worker-deployment.yaml
│   │   │   ├── lmtpd-deployment.yaml
│   │   │   ├── message-handler-deployment.yaml
│   │   │   ├── minio-deployment.yaml
│   │   │   ├── nats-deployment.yaml
│   │   │   ├── redis-deployment.yaml
│   │   │   └── smtp-deployment.yaml
│   │   ├── jobs/
│   │   │   ├── cli-admin-creation.yaml
│   │   │   ├── cli-dev-creation.yaml
│   │   │   ├── cli-mail-import.yaml
│   │   │   └── cli-setup.yaml
│   │   ├── services/
│   │   │   ├── apiv1-service.yaml
│   │   │   ├── apiv2-service.yaml
│   │   │   ├── cassandra-service.yaml
│   │   │   ├── elasticsearch-service.yaml
│   │   │   ├── external-go-service.yaml
│   │   │   ├── external-python-service.yaml
│   │   │   ├── frontend-service.yaml
│   │   │   ├── lmtpd-service.yaml
│   │   │   ├── minio-service.yaml
│   │   │   ├── nats-service.yaml
│   │   │   ├── redis-service.yaml
│   │   │   └── smtp-service.yaml
│   │   └── volumeclaims/
│   │       ├── db-persistentvolumeclaim.yaml
│   │       ├── index-persistentvolumeclaim.yaml
│   │       └── store-persistentvolumeclaim.yaml
│   ├── make_release
│   ├── makefile
│   ├── manage_package
│   ├── manage_package-requirements.txt
│   ├── migrations/
│   │   ├── ES_mappings_v2.json
│   │   ├── add_delivered_column_to_raw-message_table.cql
│   │   ├── add_temp_id_to_attachment_type.cql
│   │   ├── fill_message_is_received.py
│   │   ├── index_migration_v0_to_v2.py
│   │   ├── index_migration_v2_to_v3.py
│   │   ├── index_migration_v3_to_v4.py
│   │   ├── index_migration_v4_to_v5.py
│   │   ├── index_migration_v5_to_v6.py
│   │   ├── set_date_sort_in_db.py
│   │   └── update_ecdsa_key.py
│   ├── packages.yaml
│   ├── publish-images.sh
│   ├── registry.conf.template
│   ├── run-tests.sh
│   ├── setup-virtualenv.sh
│   ├── start.sh
│   ├── stop.sh
│   └── storybook/
│       ├── .storybook/
│       │   ├── addons.js
│       │   ├── config.js
│       │   └── webpack.config.js
│       ├── README.md
│       ├── package.json
│       └── stories/
│           ├── CHANGELOG.md
│           ├── Changelog.jsx
│           ├── Guideline/
│           │   ├── index.jsx
│           │   └── style.scss
│           ├── Welcome.jsx
│           ├── components/
│           │   ├── BlockList.jsx
│           │   ├── CollectionFieldGroup.jsx
│           │   ├── ContactDetails.jsx
│           │   ├── FormGrid.jsx
│           │   ├── Link.jsx
│           │   ├── MessageList.jsx
│           │   ├── PasswordStrength.jsx
│           │   ├── PiBar.jsx
│           │   ├── Reply.jsx
│           │   ├── Subtitle.jsx
│           │   └── TagsForm.jsx
│           ├── index.jsx
│           ├── layouts/
│           │   ├── ContactBook.jsx
│           │   ├── Devices.jsx
│           │   ├── SigninPage.jsx
│           │   └── SignupPage.jsx
│           └── presenters/
│               ├── Code.jsx
│               ├── ComponentWrapper.jsx
│               └── index.js
├── doc/
│   ├── architecture/
│   │   ├── Repository_structure.md
│   │   └── assets/
│   │       └── stack_frontend_dev_2017-03-09.puml
│   ├── devops/
│   │   ├── continous-integration.md
│   │   ├── docker-&-registry.md
│   │   └── kube_survival_guide.md
│   ├── index.md
│   ├── install/
│   │   ├── frontend-development.md
│   │   ├── minikube-local-development.md
│   │   └── native-installation.md
│   ├── install.md
│   ├── monitoring-debug/
│   │   └── analyse-frontend-bundle.md
│   ├── release/
│   │   ├── Communication.md
│   │   ├── Guidelines.md
│   │   ├── README.md
│   │   └── deploy_kubernetes.md
│   ├── specifications/
│   │   ├── attachments/
│   │   │   ├── assets/
│   │   │   │   └── management.puml
│   │   │   └── index.md
│   │   ├── client/
│   │   │   ├── architecture.md
│   │   │   ├── frontend-data-flow.md
│   │   │   └── routing.md
│   │   ├── contact/
│   │   │   ├── assets/
│   │   │   │   └── discover_contact_from_email.uml
│   │   │   ├── index.md
│   │   │   └── vcard_doc.md
│   │   ├── discussions/
│   │   │   ├── assets/
│   │   │   │   └── delete_discussion.uml
│   │   │   └── delete_discussion.md
│   │   ├── email-protocol/
│   │   │   ├── assets/
│   │   │   │   ├── email-delivery-inbound-rpc.puml
│   │   │   │   ├── email-delivery-inbound.puml
│   │   │   │   ├── email-delivery-outbound.puml
│   │   │   │   ├── email-inbound-delivery-poc.puml
│   │   │   │   ├── imap-outbound-process.puml
│   │   │   │   └── smtp-delivery-inbound-closeup.puml
│   │   │   ├── imap-binaries.md
│   │   │   └── index.md
│   │   ├── identities/
│   │   │   ├── Remote-identities-creation-diagram.puml
│   │   │   ├── index.md
│   │   │   └── remote-identities.md
│   │   ├── message/
│   │   │   ├── assets/
│   │   │   │   ├── message-create-save-send.puml
│   │   │   │   ├── message-create-save-send_nats_async.puml
│   │   │   │   └── message_discussion_association.puml
│   │   │   └── index.md
│   │   ├── messages-drafts-discussions-routes/
│   │   │   └── index-fr.md
│   │   ├── messaging-system/
│   │   │   └── index.md
│   │   ├── notification/
│   │   │   ├── API-fr.md
│   │   │   ├── assets/
│   │   │   │   └── client-message-sequence.puml
│   │   │   └── frontend.md
│   │   ├── patch/
│   │   │   └── index.md
│   │   ├── protocol-implementation.md
│   │   ├── pwa/
│   │   │   ├── assets/
│   │   │   │   └── sequence.puml
│   │   │   └── pwa.md
│   │   ├── remote-identities/
│   │   │   ├── assets/
│   │   │   │   └── twitter-oauth.puml
│   │   │   ├── gmail.md
│   │   │   ├── oauth.md
│   │   │   └── twitter.md
│   │   ├── rest-api/
│   │   │   └── index.md
│   │   ├── scss-reference.md
│   │   ├── search/
│   │   │   └── index.md
│   │   ├── user-and-device-identification/
│   │   │   ├── assets/
│   │   │   │   ├── authenticate_new_device.uml
│   │   │   │   ├── create_user_and_device.uml
│   │   │   │   ├── user_and_device_authentication.uml
│   │   │   │   └── user_update_credential.uml
│   │   │   ├── index.md
│   │   │   └── revoke-devices.md
│   │   └── username/
│   │       └── index.md
│   ├── tools.md
│   └── welcome.md
└── src/
    ├── backend/
    │   ├── Dockerfile.caliopen-go
    │   ├── Dockerfile.caliopen-python
    │   ├── Dockerfile.cli
    │   ├── Dockerfile.cli-ml
    │   ├── Dockerfile.go-api
    │   ├── Dockerfile.go-lmtp
    │   ├── Dockerfile.identity-poller
    │   ├── Dockerfile.imap-worker
    │   ├── Dockerfile.mastodon-worker
    │   ├── Dockerfile.mq-worker
    │   ├── Dockerfile.py-api
    │   ├── Dockerfile.twitter-worker
    │   ├── brokers/
    │   │   ├── go.emails/
    │   │   │   ├── README.md
    │   │   │   ├── broker.go
    │   │   │   ├── email.go
    │   │   │   ├── encrypt.go
    │   │   │   ├── inbound.go
    │   │   │   └── outbound.go
    │   │   ├── go.mastodon/
    │   │   │   ├── broker.go
    │   │   │   ├── direct_messages.go
    │   │   │   ├── doc.go
    │   │   │   ├── inbound.go
    │   │   │   └── outbound.go
    │   │   └── go.twitter/
    │   │       ├── broker.go
    │   │       ├── direct_messages.go
    │   │       ├── doc.go
    │   │       ├── inbound.go
    │   │       └── outbound.go
    │   ├── components/
    │   │   ├── py.data/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_data/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── interface.py
    │   │   │   │   ├── provider.py
    │   │   │   │   └── store.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.pgp/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── MANIFEST.in
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_pgp/
    │   │   │   │   ├── __init__.py
    │   │   │   │   └── keys/
    │   │   │   │       ├── __init__.py
    │   │   │   │       ├── base.py
    │   │   │   │       ├── contact.py
    │   │   │   │       ├── discoverer.py
    │   │   │   │       ├── hkp.py
    │   │   │   │       ├── keybase.py
    │   │   │   │       └── rfc7929.py
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.pi/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_pi/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── features/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── contact.py
    │   │   │   │   │   ├── device.py
    │   │   │   │   │   ├── helpers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── histogram.py
    │   │   │   │   │   │   ├── importance_level.py
    │   │   │   │   │   │   ├── ingress_path.py
    │   │   │   │   │   │   └── spam.py
    │   │   │   │   │   ├── mail.py
    │   │   │   │   │   └── types.py
    │   │   │   │   ├── qualifiers/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── base.py
    │   │   │   │   │   ├── contact.py
    │   │   │   │   │   ├── device.py
    │   │   │   │   │   ├── mail.py
    │   │   │   │   │   ├── mastodon.py
    │   │   │   │   │   └── twitter.py
    │   │   │   │   └── tests/
    │   │   │   │       ├── fixtures/
    │   │   │   │       │   ├── dkim1.eml
    │   │   │   │       │   ├── pgp_crypted_1.eml
    │   │   │   │       │   ├── pgpsigned1.elm
    │   │   │   │       │   ├── spam1.eml
    │   │   │   │       │   ├── spam2.eml
    │   │   │   │       │   └── spam3.eml
    │   │   │   │       ├── test_features.py
    │   │   │   │       ├── test_importance_level.py
    │   │   │   │       └── test_spam.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   └── py.tag/
    │   │       ├── CHANGES.rst
    │   │       ├── README.rst
    │   │       ├── caliopen_tag/
    │   │       │   ├── __init__.py
    │   │       │   ├── models_manager/
    │   │       │   │   ├── __init__.py
    │   │       │   │   ├── data_manager.py
    │   │       │   │   └── manager.py
    │   │       │   ├── taggers/
    │   │       │   │   ├── __init__.py
    │   │       │   │   └── tagger.py
    │   │       │   ├── tests/
    │   │       │   │   ├── test_model_manager.py
    │   │       │   │   └── test_tag.py
    │   │       │   └── utils.py
    │   │       ├── requirements.deps
    │   │       ├── setup.cfg
    │   │       └── setup.py
    │   ├── configs/
    │   │   ├── apiv1-nginx.conf
    │   │   ├── apiv1-supervisord.conf
    │   │   ├── apiv1.ini
    │   │   ├── apiv2.yaml
    │   │   ├── caliopen-api.development.ini
    │   │   ├── caliopen.yaml
    │   │   ├── caliopen.yaml.template
    │   │   ├── idpoller.yaml
    │   │   ├── imapworker.yaml
    │   │   ├── lmtp.yaml
    │   │   ├── mastodonworker.yaml
    │   │   ├── swagger.json
    │   │   └── twitterworker.yaml
    │   ├── defs/
    │   │   ├── go-objects/
    │   │   │   ├── actions_payload.go
    │   │   │   ├── attachment.go
    │   │   │   ├── cache.go
    │   │   │   ├── common.go
    │   │   │   ├── configs.go
    │   │   │   ├── constants.go
    │   │   │   ├── contact.go
    │   │   │   ├── credentials.go
    │   │   │   ├── crypto_keys.go
    │   │   │   ├── device.go
    │   │   │   ├── discussion.go
    │   │   │   ├── email.go
    │   │   │   ├── errors.go
    │   │   │   ├── external_references.go
    │   │   │   ├── im.go
    │   │   │   ├── location.go
    │   │   │   ├── message.go
    │   │   │   ├── nats.go
    │   │   │   ├── notification.go
    │   │   │   ├── notification_test.go
    │   │   │   ├── organization.go
    │   │   │   ├── participant.go
    │   │   │   ├── participants_test.go
    │   │   │   ├── phone.go
    │   │   │   ├── postal_address.go
    │   │   │   ├── privacy_features.go
    │   │   │   ├── privacy_index.go
    │   │   │   ├── provider.go
    │   │   │   ├── raw_message.go
    │   │   │   ├── search.go
    │   │   │   ├── settings.go
    │   │   │   ├── social_identity.go
    │   │   │   ├── tag.go
    │   │   │   ├── tls.go
    │   │   │   ├── user.go
    │   │   │   ├── user_identity.go
    │   │   │   ├── username.go
    │   │   │   └── uuid.go
    │   │   ├── nats-messages/
    │   │   │   ├── IMAPworkers_FetchOrder.yaml
    │   │   │   ├── SMTPqueue_ack_msg.yaml
    │   │   │   ├── UpdateContactPI_msg.yaml
    │   │   │   ├── inboundSMTP_deliver_msg.yaml
    │   │   │   └── outboundSMTP_deliver_msg.yaml
    │   │   ├── notifiers/
    │   │   │   └── templates/
    │   │   │       ├── email-device-validation.yaml
    │   │   │       ├── email-onboarding.yaml
    │   │   │       ├── email-reset-password-link.yaml
    │   │   │       └── email-welcome.yaml
    │   │   └── rest-api/
    │   │       ├── objects/
    │   │       │   ├── Actions.yaml
    │   │       │   ├── Attachment.yaml
    │   │       │   ├── Authentication.yaml
    │   │       │   ├── Contact.yaml
    │   │       │   ├── ContactIdentity.yaml
    │   │       │   ├── DefaultDevice.yaml
    │   │       │   ├── Device.yaml
    │   │       │   ├── DeviceLocation.yaml
    │   │       │   ├── Discussion.yaml
    │   │       │   ├── ECKey.yaml
    │   │       │   ├── Email.yaml
    │   │       │   ├── Error.yaml
    │   │       │   ├── ExternalReferences.yaml
    │   │       │   ├── IM.yaml
    │   │       │   ├── Identity.yaml
    │   │       │   ├── Message.yaml
    │   │       │   ├── MessageV2.yaml
    │   │       │   ├── NewContact.yaml
    │   │       │   ├── NewDevice.yaml
    │   │       │   ├── NewEmail.yaml
    │   │       │   ├── NewIM.yaml
    │   │       │   ├── NewMessage.yaml
    │   │       │   ├── NewMessageV2.yaml
    │   │       │   ├── NewOrganization.yaml
    │   │       │   ├── NewPhone.yaml
    │   │       │   ├── NewPostalAddress.yaml
    │   │       │   ├── NewPublicKey.yaml
    │   │       │   ├── NewSocialIdentity.yaml
    │   │       │   ├── NewTag.yaml
    │   │       │   ├── NewUser.yaml
    │   │       │   ├── NewUserIdentity.yaml
    │   │       │   ├── Notification.yaml
    │   │       │   ├── Organization.yaml
    │   │       │   ├── PI.yaml
    │   │       │   ├── PIMessage.yaml
    │   │       │   ├── Participant.yaml
    │   │       │   ├── ParticipantSuggest.yaml
    │   │       │   ├── Phone.yaml
    │   │       │   ├── PostalAddress.yaml
    │   │       │   ├── PrivacyFeatures.yaml
    │   │       │   ├── PublicKey.yaml
    │   │       │   ├── SearchResponse.yaml
    │   │       │   ├── Settings.yaml
    │   │       │   ├── ShortContact.yaml
    │   │       │   ├── SocialIdentity.yaml
    │   │       │   ├── Tag.yaml
    │   │       │   ├── User.yaml
    │   │       │   └── UserIdentity.yaml
    │   │       ├── paths/
    │   │       │   ├── authentications.yaml
    │   │       │   ├── contacts.yaml
    │   │       │   ├── contactsV2.yaml
    │   │       │   ├── devices.yaml
    │   │       │   ├── discussions.yaml
    │   │       │   ├── files.yaml
    │   │       │   ├── hashdiscussion.yaml
    │   │       │   ├── identities.yaml
    │   │       │   ├── imports.yaml
    │   │       │   ├── me.yaml
    │   │       │   ├── messages.yaml
    │   │       │   ├── messagesV2.yaml
    │   │       │   ├── notifications.yaml
    │   │       │   ├── participants.yaml
    │   │       │   ├── passwords.yaml
    │   │       │   ├── providers.yaml
    │   │       │   ├── raws.yaml
    │   │       │   ├── search.yaml
    │   │       │   ├── settings.yaml
    │   │       │   ├── tags.yaml
    │   │       │   └── users.yaml
    │   │       └── swagger-root.yaml
    │   ├── doc/
    │   │   └── api/
    │   │       ├── README.md
    │   │       └── swagger.html
    │   ├── interfaces/
    │   │   ├── NATS/
    │   │   │   ├── go.mockednats/
    │   │   │   │   └── nats.go
    │   │   │   └── py.client/
    │   │   │       ├── CHANGES.rst
    │   │   │       ├── MANIFEST.in
    │   │   │       ├── README.rst
    │   │   │       ├── caliopen_nats/
    │   │   │       │   ├── __init__.py
    │   │   │       │   ├── delivery.py
    │   │   │       │   ├── listener.py
    │   │   │       │   └── subscribers.py
    │   │   │       ├── requirements.deps
    │   │   │       ├── setup.cfg
    │   │   │       └── setup.py
    │   │   └── REST/
    │   │       ├── go.server/
    │   │       │   ├── README.md
    │   │       │   ├── api_server.go
    │   │       │   ├── cmd/
    │   │       │   │   └── caliopen_rest/
    │   │       │   │       ├── cli_cmds/
    │   │       │   │       │   ├── root.go
    │   │       │   │       │   └── serve.go
    │   │       │   │       └── main.go
    │   │       │   ├── dump_request.go
    │   │       │   ├── errors.go
    │   │       │   ├── middlewares/
    │   │       │   │   ├── authentication.go
    │   │       │   │   ├── config.go
    │   │       │   │   └── swagger.go
    │   │       │   ├── operations/
    │   │       │   │   ├── contacts/
    │   │       │   │   │   ├── Identities.go
    │   │       │   │   │   ├── contacts.go
    │   │       │   │   │   └── keys.go
    │   │       │   │   ├── devices/
    │   │       │   │   │   └── devices.go
    │   │       │   │   ├── discussions/
    │   │       │   │   │   └── discussions.go
    │   │       │   │   ├── helpers.go
    │   │       │   │   ├── identities/
    │   │       │   │   │   └── identities.go
    │   │       │   │   ├── imports/
    │   │       │   │   │   └── import.go
    │   │       │   │   ├── messages/
    │   │       │   │   │   ├── actions.go
    │   │       │   │   │   ├── attachments.go
    │   │       │   │   │   └── messages.go
    │   │       │   │   ├── notifications/
    │   │       │   │   │   └── notifications.go
    │   │       │   │   ├── participants/
    │   │       │   │   │   ├── discussion.go
    │   │       │   │   │   └── suggest.go
    │   │       │   │   ├── providers/
    │   │       │   │   │   ├── oauth-test.html
    │   │       │   │   │   └── providers.go
    │   │       │   │   ├── search.go
    │   │       │   │   ├── tags/
    │   │       │   │   │   └── tags.go
    │   │       │   │   └── users/
    │   │       │   │       ├── user.go
    │   │       │   │       └── username.go
    │   │       │   └── proxy.go
    │   │       └── py.server/
    │   │           ├── CHANGES.rst
    │   │           ├── MANIFEST.in
    │   │           ├── README.rst
    │   │           ├── caliopen_api/
    │   │           │   ├── __init__.py
    │   │           │   ├── base/
    │   │           │   │   ├── __init__.py
    │   │           │   │   ├── config.py
    │   │           │   │   ├── context.py
    │   │           │   │   ├── deserializer.py
    │   │           │   │   ├── errors.py
    │   │           │   │   ├── exception.py
    │   │           │   │   └── renderer.py
    │   │           │   ├── discussion/
    │   │           │   │   ├── __init__.py
    │   │           │   │   ├── config.py
    │   │           │   │   └── participants.py
    │   │           │   ├── message/
    │   │           │   │   ├── __init__.py
    │   │           │   │   ├── config.py
    │   │           │   │   └── message.py
    │   │           │   └── user/
    │   │           │       ├── __init__.py
    │   │           │       ├── authentication.py
    │   │           │       ├── config.py
    │   │           │       ├── contact.py
    │   │           │       ├── imports.py
    │   │           │       ├── settings.py
    │   │           │       ├── user.py
    │   │           │       └── util.py
    │   │           ├── requirements.deps
    │   │           ├── setup.cfg
    │   │           └── setup.py
    │   ├── main/
    │   │   ├── go.backends/
    │   │   │   ├── AttachmentsInterfaces.go
    │   │   │   ├── CacheInterfaces.go
    │   │   │   ├── ContactsInterfaces.go
    │   │   │   ├── CredentialsInterfaces.go
    │   │   │   ├── DevicesInterfaces.go
    │   │   │   ├── DiscussionsInterface.go
    │   │   │   ├── IdentitiesInterface.go
    │   │   │   ├── KeysInterfaces.go
    │   │   │   ├── LDAInterfaces.go
    │   │   │   ├── MessagesInterfaces.go
    │   │   │   ├── NotificationsInterfaces.go
    │   │   │   ├── ProvidersInterfaces.go
    │   │   │   ├── RESTInterfaces.go
    │   │   │   ├── TagsInterfaces.go
    │   │   │   ├── UrisInterface.go
    │   │   │   ├── UsersInterfaces.go
    │   │   │   ├── backendstest/
    │   │   │   │   ├── APIstore.go
    │   │   │   │   ├── Attachments.go
    │   │   │   │   ├── Cache.go
    │   │   │   │   ├── Contacts.go
    │   │   │   │   ├── Credentials.go
    │   │   │   │   ├── Devices.go
    │   │   │   │   ├── Discussions.go
    │   │   │   │   ├── Identities.go
    │   │   │   │   ├── Keys.go
    │   │   │   │   ├── LDA.go
    │   │   │   │   ├── Messages.go
    │   │   │   │   ├── Notifications.go
    │   │   │   │   ├── Providers.go
    │   │   │   │   ├── Tags.go
    │   │   │   │   ├── UrisInterface.go
    │   │   │   │   ├── UserNames.go
    │   │   │   │   ├── Users.go
    │   │   │   │   └── testdata.go
    │   │   │   ├── cache/
    │   │   │   │   ├── authentication.go
    │   │   │   │   ├── cache.go
    │   │   │   │   ├── devicevalidation.go
    │   │   │   │   ├── devicevalidation_test.go
    │   │   │   │   ├── oauthsessions.go
    │   │   │   │   ├── passwordreset.go
    │   │   │   │   └── redis.go
    │   │   │   ├── index/
    │   │   │   │   └── elasticsearch/
    │   │   │   │       ├── broad_search.go
    │   │   │   │       ├── contacts.go
    │   │   │   │       ├── discussions.go
    │   │   │   │       ├── elasticsearch.go
    │   │   │   │       ├── messages.go
    │   │   │   │       └── user_recipients_lookup.go
    │   │   │   └── store/
    │   │   │       ├── cassandra/
    │   │   │       │   ├── attachments.go
    │   │   │       │   ├── cassandra.go
    │   │   │       │   ├── contacts.go
    │   │   │       │   ├── contacts_test.go
    │   │   │       │   ├── credentials.go
    │   │   │       │   ├── devices.go
    │   │   │       │   ├── discussions.go
    │   │   │       │   ├── discussions_test.go
    │   │   │       │   ├── emails.go
    │   │   │       │   ├── identities.go
    │   │   │       │   ├── keys.go
    │   │   │       │   ├── lookups.go
    │   │   │       │   ├── messages.go
    │   │   │       │   ├── notifications.go
    │   │   │       │   ├── participant_lookup.go
    │   │   │       │   ├── providers.go
    │   │   │       │   ├── raw_messages.go
    │   │   │       │   ├── related.go
    │   │   │       │   ├── settings.go
    │   │   │       │   ├── tags.go
    │   │   │       │   ├── usernames.go
    │   │   │       │   └── users.go
    │   │   │       ├── object_store/
    │   │   │       │   ├── attachments.go
    │   │   │       │   ├── minio.go
    │   │   │       │   ├── objects.go
    │   │   │       │   └── raw_messages.go
    │   │   │       └── vault/
    │   │   │           ├── credentials.go
    │   │   │           ├── hvault_interface.go
    │   │   │           └── vault_client.go
    │   │   ├── go.main/
    │   │   │   ├── caliopen.go
    │   │   │   ├── contact/
    │   │   │   │   ├── contact.go
    │   │   │   │   ├── contact_test.go
    │   │   │   │   └── vcard.go
    │   │   │   ├── facilities/
    │   │   │   │   ├── Messaging/
    │   │   │   │   │   ├── facility.go
    │   │   │   │   │   └── facility_test.go
    │   │   │   │   ├── Notifications/
    │   │   │   │   │   ├── batch.go
    │   │   │   │   │   ├── batch_test.go
    │   │   │   │   │   ├── email.go
    │   │   │   │   │   ├── facility.go
    │   │   │   │   │   ├── queue.go
    │   │   │   │   │   └── templating.go
    │   │   │   │   └── REST/
    │   │   │   │       ├── RESTfacility.go
    │   │   │   │       ├── attachment.go
    │   │   │   │       ├── contacts.go
    │   │   │   │       ├── contacts_test.go
    │   │   │   │       ├── devices.go
    │   │   │   │       ├── devices_test.go
    │   │   │   │       ├── discussions.go
    │   │   │   │       ├── draft.go
    │   │   │   │       ├── identities.go
    │   │   │   │       ├── keys.go
    │   │   │   │       ├── message.go
    │   │   │   │       ├── nats.go
    │   │   │   │       ├── providers.go
    │   │   │   │       ├── search.go
    │   │   │   │       ├── settings.go
    │   │   │   │       ├── suggest_participants.go
    │   │   │   │       ├── tags.go
    │   │   │   │       ├── username.go
    │   │   │   │       └── users.go
    │   │   │   ├── helpers/
    │   │   │   │   ├── contact.go
    │   │   │   │   ├── discussion.go
    │   │   │   │   ├── discussion_test.go
    │   │   │   │   ├── filesystem.go
    │   │   │   │   ├── misc.go
    │   │   │   │   ├── netTest.go
    │   │   │   │   ├── patch.go
    │   │   │   │   └── uuid.go
    │   │   │   ├── messages/
    │   │   │   │   └── messages.go
    │   │   │   ├── pi/
    │   │   │   │   ├── identities.go
    │   │   │   │   └── message.go
    │   │   │   └── users/
    │   │   │       ├── oauth2.go
    │   │   │       └── password.go
    │   │   ├── py.main/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── MANIFEST.in
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_main/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── common/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── base.py
    │   │   │   │   │   │   ├── pubkey.py
    │   │   │   │   │   │   └── related.py
    │   │   │   │   │   ├── errors.py
    │   │   │   │   │   ├── helpers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── normalize.py
    │   │   │   │   │   │   └── strings.py
    │   │   │   │   │   ├── interfaces/
    │   │   │   │   │   │   ├── IO.py
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── parser.py
    │   │   │   │   │   │   └── storage.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── base.py
    │   │   │   │   │   │   └── tag.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── pubkey.py
    │   │   │   │   │   │   ├── tag.py
    │   │   │   │   │   │   └── types.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── pubkey.py
    │   │   │   │   │       └── tag.py
    │   │   │   │   ├── contact/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── contact.py
    │   │   │   │   │   │   ├── email.py
    │   │   │   │   │   │   ├── identity.py
    │   │   │   │   │   │   ├── im.py
    │   │   │   │   │   │   ├── organization.py
    │   │   │   │   │   │   ├── phone.py
    │   │   │   │   │   │   └── postal_address.py
    │   │   │   │   │   ├── parameters.py
    │   │   │   │   │   ├── parsers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── vcard.py
    │   │   │   │   │   ├── returns.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── contact.py
    │   │   │   │   │       └── contact_index.py
    │   │   │   │   ├── device/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core.py
    │   │   │   │   │   ├── parameters.py
    │   │   │   │   │   └── store.py
    │   │   │   │   ├── discussion/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── discussion.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── discussion.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── discussion.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── discussion_index.py
    │   │   │   │   │       └── discussion_lookup.py
    │   │   │   │   ├── message/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── external_references.py
    │   │   │   │   │   │   └── raw.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── attachment.py
    │   │   │   │   │   │   ├── external_references.py
    │   │   │   │   │   │   └── message.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── attachment.py
    │   │   │   │   │   │   ├── draft.py
    │   │   │   │   │   │   ├── external_references.py
    │   │   │   │   │   │   └── message.py
    │   │   │   │   │   ├── parsers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── mail.py
    │   │   │   │   │   │   ├── mastodon.py
    │   │   │   │   │   │   └── twitter.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── attachment.py
    │   │   │   │   │       ├── attachment_index.py
    │   │   │   │   │       ├── external_references.py
    │   │   │   │   │       ├── external_references_index.py
    │   │   │   │   │       ├── message.py
    │   │   │   │   │       ├── message_index.py
    │   │   │   │   │       └── raw.py
    │   │   │   │   ├── notification/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core.py
    │   │   │   │   │   └── store.py
    │   │   │   │   ├── participant/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── participant.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── participant.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── participant.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── participant.py
    │   │   │   │   │       └── participant_index.py
    │   │   │   │   ├── pi/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── objects.py
    │   │   │   │   │   └── parameters.py
    │   │   │   │   ├── protocol/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── provider.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       └── provider.py
    │   │   │   │   ├── tests/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── fixtures/
    │   │   │   │   │   │   ├── mail/
    │   │   │   │   │   │   │   ├── pgp_crypted_1.eml
    │   │   │   │   │   │   │   └── pgp_signed_1.eml
    │   │   │   │   │   │   └── vcard/
    │   │   │   │   │   │       ├── multi.vcf
    │   │   │   │   │   │       ├── rfc2425-1.vcard
    │   │   │   │   │   │       ├── rfc2425-2.vcard
    │   │   │   │   │   │       ├── rfc2425-3.vcard
    │   │   │   │   │   │       ├── rfc2426-1.vcard
    │   │   │   │   │   │       ├── rfc2426-2.vcard
    │   │   │   │   │   │       ├── rfc2426-3.vcard
    │   │   │   │   │   │       ├── rfc2426-4.vcard
    │   │   │   │   │   │       ├── rfc2426-5.vcard
    │   │   │   │   │   │       ├── vcard1.vcf
    │   │   │   │   │   │       ├── vcard2.vcf
    │   │   │   │   │   │       └── vcard3.vcf
    │   │   │   │   │   └── parsers/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── test_email.py
    │   │   │   │   │       ├── test_mail.py
    │   │   │   │   │       └── test_vcard.py
    │   │   │   │   └── user/
    │   │   │   │       ├── __init__.py
    │   │   │   │       ├── core/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── identity.py
    │   │   │   │       │   ├── setups.py
    │   │   │   │       │   └── user.py
    │   │   │   │       ├── helpers/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── mergePatch.py
    │   │   │   │       │   └── validators.py
    │   │   │   │       ├── objects/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── device.py
    │   │   │   │       │   ├── identity.py
    │   │   │   │       │   ├── settings.py
    │   │   │   │       │   └── tag.py
    │   │   │   │       ├── parameters/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── identity.py
    │   │   │   │       │   ├── settings.py
    │   │   │   │       │   ├── tag.py
    │   │   │   │       │   └── user.py
    │   │   │   │       ├── returns/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   └── user.py
    │   │   │   │       └── store/
    │   │   │   │           ├── __init__.py
    │   │   │   │           ├── identity.py
    │   │   │   │           ├── tag.py
    │   │   │   │           ├── user.py
    │   │   │   │           └── user_index.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   └── py.storage/
    │   │       ├── CHANGES.rst
    │   │       ├── MANIFEST.in
    │   │       ├── README.rst
    │   │       ├── caliopen_storage/
    │   │       │   ├── __init__.py
    │   │       │   ├── config.py
    │   │       │   ├── core/
    │   │       │   │   ├── __init__.py
    │   │       │   │   ├── base.py
    │   │       │   │   ├── mixin.py
    │   │       │   │   └── registry.py
    │   │       │   ├── exception.py
    │   │       │   ├── helpers/
    │   │       │   │   ├── __init__.py
    │   │       │   │   ├── connection.py
    │   │       │   │   └── json.py
    │   │       │   ├── parameters.py
    │   │       │   ├── returns.py
    │   │       │   └── store/
    │   │       │       ├── __init__.py
    │   │       │       ├── mixin.py
    │   │       │       └── model.py
    │   │       ├── setup.cfg
    │   │       └── setup.py
    │   ├── protocols/
    │   │   ├── go.imap/
    │   │   │   ├── cmd/
    │   │   │   │   ├── imapctl/
    │   │   │   │   │   ├── cli_cmds/
    │   │   │   │   │   │   ├── addremote.go
    │   │   │   │   │   │   ├── fullfetch.go
    │   │   │   │   │   │   ├── root.go
    │   │   │   │   │   │   └── syncremote.go
    │   │   │   │   │   └── main.go
    │   │   │   │   └── imapworker/
    │   │   │   │       ├── cli_cmds/
    │   │   │   │       │   ├── root.go
    │   │   │   │       │   └── start.go
    │   │   │   │       └── main.go
    │   │   │   ├── config.go
    │   │   │   ├── fetcher.go
    │   │   │   ├── imap.go
    │   │   │   ├── imap_test.go
    │   │   │   ├── lda.go
    │   │   │   ├── sender.go
    │   │   │   ├── sender_test.go
    │   │   │   ├── worker.go
    │   │   │   └── worker_test.go
    │   │   ├── go.mastodon/
    │   │   │   ├── account.go
    │   │   │   ├── cmd/
    │   │   │   │   └── mastodonworker/
    │   │   │   │       ├── cli_cmds/
    │   │   │   │       │   ├── root.go
    │   │   │   │       │   └── start.go
    │   │   │   │       └── main.go
    │   │   │   ├── messaging.go
    │   │   │   └── worker.go
    │   │   ├── go.smtp/
    │   │   │   ├── cmd/
    │   │   │   │   └── caliopen_lmtpd/
    │   │   │   │       ├── cli_cmds/
    │   │   │   │       │   ├── root.go
    │   │   │   │       │   └── serve.go
    │   │   │   │       └── main.go
    │   │   │   ├── config.go
    │   │   │   ├── envelope.go
    │   │   │   ├── lda.go
    │   │   │   ├── lmtpd.go
    │   │   │   ├── oauth.go
    │   │   │   ├── protocol.go
    │   │   │   ├── receiver.go
    │   │   │   ├── server.go
    │   │   │   └── submitter.go
    │   │   └── go.twitter/
    │   │       ├── account.go
    │   │       ├── account_test.go
    │   │       ├── cmd/
    │   │       │   └── twitterworker/
    │   │       │       ├── cli_cmds/
    │   │       │       │   ├── root.go
    │   │       │       │   └── start.go
    │   │       │       └── main.go
    │   │       ├── messaging.go
    │   │       ├── messaging_test.go
    │   │       ├── worker.go
    │   │       └── worker_test.go
    │   ├── tools/
    │   │   ├── go.CLI/
    │   │   │   └── cmd/
    │   │   │       └── gocaliopen/
    │   │   │           ├── cli_cmds/
    │   │   │           │   ├── changeIdentitiyEmailProtocol.go
    │   │   │           │   ├── changeUserIdentitiesCredentialsKeys.go
    │   │   │           │   ├── fixMissingParticipants.go
    │   │   │           │   ├── identitiesMigration.go
    │   │   │           │   └── root.go
    │   │   │           └── main.go
    │   │   ├── py.CLI/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_cli/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── cli.py
    │   │   │   │   ├── commands/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── compute.py
    │   │   │   │   │   ├── copy_model.py
    │   │   │   │   │   ├── create_user.py
    │   │   │   │   │   ├── dump_indexes_mappings.py
    │   │   │   │   │   ├── dump_model.py
    │   │   │   │   │   ├── import_email.py
    │   │   │   │   │   ├── import_vcard.py
    │   │   │   │   │   ├── inject_email.py
    │   │   │   │   │   ├── migrate_index.py
    │   │   │   │   │   ├── reserved_names.py
    │   │   │   │   │   ├── resync_index.py
    │   │   │   │   │   ├── resync_shard_index.py
    │   │   │   │   │   ├── setup.py
    │   │   │   │   │   ├── setup_notifications_ttls.py
    │   │   │   │   │   ├── setup_storage.py
    │   │   │   │   │   └── shell.py
    │   │   │   │   └── utils/
    │   │   │   │       ├── __init__.py
    │   │   │   │       └── user_token.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.ML/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_climl/
    │   │   │   │   ├── __init__.py
    │   │   │   │   └── cli.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.doc/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_api_doc/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── config.py
    │   │   │   │   └── swagger-ui/
    │   │   │   │       ├── css/
    │   │   │   │       │   ├── print.css
    │   │   │   │       │   ├── reset.css
    │   │   │   │       │   ├── screen.css
    │   │   │   │       │   ├── style.css
    │   │   │   │       │   └── typography.css
    │   │   │   │       ├── index.html
    │   │   │   │       ├── lang/
    │   │   │   │       │   ├── ca.js
    │   │   │   │       │   ├── el.js
    │   │   │   │       │   ├── en.js
    │   │   │   │       │   ├── es.js
    │   │   │   │       │   ├── fr.js
    │   │   │   │       │   ├── geo.js
    │   │   │   │       │   ├── it.js
    │   │   │   │       │   ├── ja.js
    │   │   │   │       │   ├── ko-kr.js
    │   │   │   │       │   ├── pl.js
    │   │   │   │       │   ├── pt.js
    │   │   │   │       │   ├── ru.js
    │   │   │   │       │   ├── tr.js
    │   │   │   │       │   ├── translator.js
    │   │   │   │       │   └── zh-cn.js
    │   │   │   │       ├── lib/
    │   │   │   │       │   ├── backbone-min.js
    │   │   │   │       │   ├── es5-shim.js
    │   │   │   │       │   ├── handlebars-4.0.5.js
    │   │   │   │       │   ├── highlight.9.1.0.pack.js
    │   │   │   │       │   ├── highlight.9.1.0.pack_extended.js
    │   │   │   │       │   ├── marked.js
    │   │   │   │       │   ├── object-assign-pollyfill.js
    │   │   │   │       │   └── swagger-oauth.js
    │   │   │   │       ├── o2c.html
    │   │   │   │       └── swagger-ui.js
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   └── py.migrate/
    │   │       ├── CHANGES.rst
    │   │       ├── README.rst
    │   │       ├── caliopen_migrate/
    │   │       │   ├── __init__.py
    │   │       │   ├── cli.py
    │   │       │   ├── shards.py
    │   │       │   ├── user.py
    │   │       │   └── welcome_message.py
    │   │       ├── setup.cfg
    │   │       └── setup.py
    │   └── workers/
    │       └── go.remoteIDs/
    │           ├── cmd/
    │           │   └── idpoller/
    │           │       ├── cli_cmds/
    │           │       │   ├── root.go
    │           │       │   └── start.go
    │           │       └── main.go
    │           ├── identities.go
    │           ├── identities_test.go
    │           ├── idpoller.go
    │           ├── idpollertest/
    │           │   └── testsreplies.go
    │           ├── jobs.go
    │           ├── jobs_test.go
    │           ├── messaging.go
    │           ├── messaging_test.go
    │           ├── scheduler.go
    │           └── scheduler_test.go
    └── frontend/
        ├── maintenance/
        │   ├── Dockerfile
        │   ├── README.md
        │   ├── config/
        │   │   └── nginx-config-maintenance.conf
        │   ├── package.json
        │   └── src/
        │       ├── assets/
        │       │   ├── css/
        │       │   │   └── style.css
        │       │   ├── js/
        │       │   │   └── init.js
        │       │   └── scss/
        │       │       ├── params/
        │       │       │   ├── _fonts.scss
        │       │       │   ├── _grid.scss
        │       │       │   ├── _images.scss
        │       │       │   └── _variables.scss
        │       │       └── style.scss
        │       └── index.html
        ├── not_found/
        │   ├── 404.html
        │   └── assets/
        │       └── app.client.e4ae8e333ea54a53ba14.css
        └── web_application/
            ├── .babelrc
            ├── .dockerignore
            ├── .eslintrc.json
            ├── .gitignore
            ├── .prettierignore
            ├── .prettierrc.js
            ├── .stylelintrc.yml
            ├── CONTRIBUTING.md
            ├── Dockerfile
            ├── Dockerfile.caliopen-node
            ├── README.md
            ├── __mocks__/
            │   ├── fileMock.js
            │   └── styleMock.js
            ├── bin/
            │   ├── dev-server
            │   └── server
            ├── config/
            │   ├── client.default.js
            │   ├── server.default.js
            │   └── server.env-var.js
            ├── lingui.config.ts
            ├── locale/
            │   ├── de/
            │   │   └── messages.json
            │   ├── en/
            │   │   └── messages.json
            │   ├── es/
            │   │   └── messages.json
            │   └── fr/
            │       └── messages.json
            ├── package.json
            ├── postcss.config.js
            ├── public/
            │   └── privacy-policy.html
            ├── server/
            │   ├── api/
            │   │   ├── index.js
            │   │   └── lib/
            │   │       ├── api.ts
            │   │       └── sub-request-manager.js
            │   ├── app.ts
            │   ├── assets/
            │   │   └── index.js
            │   ├── auth/
            │   │   ├── index.js
            │   │   ├── lib/
            │   │   │   ├── cookie.ts
            │   │   │   ├── redirect.ts
            │   │   │   └── seal.ts
            │   │   ├── middlewares/
            │   │   │   ├── decode-cookie.ts
            │   │   │   └── index.ts
            │   │   └── router/
            │   │       ├── index.js
            │   │       ├── signin.js
            │   │       └── signup.ts
            │   ├── config/
            │   │   └── index.js
            │   ├── error/
            │   │   ├── components/
            │   │   │   └── Error/
            │   │   │       └── index.jsx
            │   │   ├── consts.ts
            │   │   ├── index.js
            │   │   └── middlewares/
            │   │       └── catch-error.js
            │   ├── express-react/
            │   │   ├── create-engine.js
            │   │   ├── index.js
            │   │   └── view.js
            │   ├── index.js
            │   ├── logger/
            │   │   ├── getLogger.js
            │   │   ├── index.js
            │   │   └── middlewares/
            │   │       └── httpLog.js
            │   └── ssr/
            │       ├── components/
            │       │   └── Bootstrap.tsx
            │       ├── index.js
            │       └── ssr-middleware.ts
            ├── src/
            │   ├── App.tsx
            │   ├── app.scss
            │   ├── components/
            │   │   ├── ActionBar/
            │   │   │   ├── components/
            │   │   │   │   ├── ActionBarButton/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   └── ActionBarWrapper/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── styles.scss
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── AdvancedSelectFieldGroup/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── AppLoader/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Badge/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── BlockList/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Brand/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Button/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Callout/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Checkbox/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── CheckboxFieldGroup/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Confirm/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── DatePickerGroup/
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── DefList/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── Dropdown/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   ├── services/
            │   │   │   │   ├── getDropdownStyle.spec.ts
            │   │   │   │   └── getDropdownStyle.ts
            │   │   │   └── style.scss
            │   │   ├── DropdownMenu/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── FieldErrors/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── FieldGroup/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Fieldset/
            │   │   │   ├── components/
            │   │   │   │   └── Legend/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── FileSize/
            │   │   │   ├── index.spec.tsx
            │   │   │   └── index.tsx
            │   │   ├── FormGrid/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Icon/
            │   │   │   ├── __snapshots__/
            │   │   │   │   └── index.spec.tsx.snap
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── InfiniteScroll/
            │   │   │   └── index.jsx
            │   │   ├── InputFile/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── InputFileGroup/
            │   │   │   ├── components/
            │   │   │   │   └── File/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── InputText/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Label/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Link/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── MenuBar/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── MessageDate/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── Modal/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── NavList/
            │   │   │   ├── components/
            │   │   │   │   └── NavItem.tsx
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── PageTitle/
            │   │   │   ├── index.jsx
            │   │   │   └── presenter.jsx
            │   │   ├── ParticipantsIconLetter/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── PasswordStrength/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── PiBar/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── PlaceholderBlock/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── PlaceholderList/
            │   │   │   ├── index.scss
            │   │   │   └── index.tsx
            │   │   ├── RadioFieldGroup/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── RawButton/
            │   │   │   └── index.tsx
            │   │   ├── Section/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── SelectFieldGroup/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── SidebarLayout/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Spinner/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Subtitle/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Switch/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── TextBlock/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── TextFieldGroup/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── TextList/
            │   │   │   ├── components/
            │   │   │   │   └── TextItem.tsx
            │   │   │   ├── index.spec.jsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Textarea/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── TextareaFieldGroup/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── Title/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── VerticalMenu/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   └── index.js
            │   ├── global.d.ts
            │   ├── hooks/
            │   │   └── forwardedRef.ts
            │   ├── image.d.ts
            │   ├── index.jsx
            │   ├── layouts/
            │   │   ├── AboutPage/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── AuthPage/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── ErrorBoundary/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Page/
            │   │   │   ├── components/
            │   │   │   │   ├── Footer/
            │   │   │   │   │   ├── footer.scss
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── HorizontalScroll/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── InstallButton/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── Navbar/
            │   │   │   │   │   └── components/
            │   │   │   │   │       ├── ApplicationTab/
            │   │   │   │   │       │   ├── application-tab.scss
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── ContactAssociationTab/
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── ContactTab/
            │   │   │   │   │       │   └── index.tsx
            │   │   │   │   │       ├── DiscussionTab/
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── ItemButton/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       ├── ItemLink/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       ├── NavbarItem/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       ├── SearchTab/
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── Tab/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       └── index.js
            │   │   │   │   ├── Navigation/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   ├── style.scss
            │   │   │   │   │   └── withTabs.jsx
            │   │   │   │   ├── NotificationCenter/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TakeATour/
            │   │   │   │       ├── components/
            │   │   │   │       │   ├── Guide/
            │   │   │   │       │   │   └── index.jsx
            │   │   │   │       │   ├── Tour/
            │   │   │   │       │   │   └── index.jsx
            │   │   │   │       │   └── TourPortal/
            │   │   │   │       │       ├── index.jsx
            │   │   │   │       │       └── style.scss
            │   │   │   │       ├── index.js
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── header.scss
            │   │   │   ├── index.jsx
            │   │   │   ├── navbar.scss
            │   │   │   └── style.scss
            │   │   ├── PageContainer/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── SearchResults/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── Settings/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   └── User/
            │   │       ├── index.js
            │   │       ├── presenter.jsx
            │   │       └── styles.scss
            │   ├── modules/
            │   │   ├── a11y/
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       └── tabIndexes.js
            │   │   ├── avatar/
            │   │   │   ├── components/
            │   │   │   │   ├── AuthorAvatarLetter/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── index.spec.jsx
            │   │   │   │   ├── AvatarLetter/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── services/
            │   │   │   │   │   │   └── stylesheet-helper/
            │   │   │   │   │   │       ├── index.js
            │   │   │   │   │   │       └── index.spec.js
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── AvatarLetterWrapper/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── ContactAvatarLetter/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── index.spec.jsx
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       └── stylesheet-helper/
            │   │   │           ├── index.js
            │   │   │           └── index.spec.js
            │   │   ├── contact/
            │   │   │   ├── actions/
            │   │   │   │   ├── deleteContacts.js
            │   │   │   │   ├── getContact.ts
            │   │   │   │   ├── loadMoreContacts.ts
            │   │   │   │   └── updateContact.js
            │   │   │   ├── components/
            │   │   │   │   ├── ContactList/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   ├── ContactItem/
            │   │   │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   │   │   └── style.scss
            │   │   │   │   │   │   └── ContactItemPlaceholder.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── WithContacts/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── consts.ts
            │   │   │   ├── hoc/
            │   │   │   │   └── withContacts.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useContacts.ts
            │   │   │   ├── index.ts
            │   │   │   ├── query.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── contactSelector.ts
            │   │   │   ├── services/
            │   │   │   │   ├── addAddressToContact.js
            │   │   │   │   ├── form.ts
            │   │   │   │   ├── format.spec.ts
            │   │   │   │   ├── format.ts
            │   │   │   │   └── identityTypes.js
            │   │   │   ├── store/
            │   │   │   │   ├── index.ts
            │   │   │   │   ├── reducer.ts
            │   │   │   │   └── selectors.ts
            │   │   │   └── types.d.ts
            │   │   ├── control/
            │   │   │   ├── components/
            │   │   │   │   ├── ComposeButton/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ComposeContactButton/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   ├── CreateContactButton/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   └── PageActions/
            │   │   │   │       ├── action-btns.scss
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   └── index.js
            │   │   ├── device/
            │   │   │   ├── actions/
            │   │   │   │   ├── requestDevice.js
            │   │   │   │   ├── requestDevices.js
            │   │   │   │   ├── revokeDevice.js
            │   │   │   │   ├── saveDevice.js
            │   │   │   │   └── verifyDevice.js
            │   │   │   ├── hooks/
            │   │   │   │   ├── useDevice.ts
            │   │   │   │   └── useDevices.ts
            │   │   │   ├── index.ts
            │   │   │   ├── selectors.ts
            │   │   │   ├── services/
            │   │   │   │   ├── clientDevice.ts
            │   │   │   │   ├── ecdsa/
            │   │   │   │   │   └── index.ts
            │   │   │   │   ├── signature/
            │   │   │   │   │   ├── index.spec.ts
            │   │   │   │   │   └── index.ts
            │   │   │   │   ├── status.js
            │   │   │   │   └── storage/
            │   │   │   │       └── index.ts
            │   │   │   └── types.d.ts
            │   │   ├── discussion/
            │   │   │   ├── actions/
            │   │   │   │   └── requestDiscussionIdForParticipants.js
            │   │   │   ├── hooks/
            │   │   │   │   └── useDiscussion.ts
            │   │   │   ├── index.js
            │   │   │   ├── query.ts
            │   │   │   └── selectors/
            │   │   │       ├── discussionDraftSelector.js
            │   │   │       ├── discussionIdSelector.js
            │   │   │       ├── discussionSelector.js
            │   │   │       └── discussionsSelector.ts
            │   │   ├── draftIdentity/
            │   │   │   ├── hooks/
            │   │   │   │   └── useAvailableIdentities.ts
            │   │   │   └── index.ts
            │   │   ├── draftMessage/
            │   │   │   ├── actions/
            │   │   │   │   ├── consolidateParticipants.js
            │   │   │   │   ├── getDefaultIdentity.js
            │   │   │   │   ├── getDefaultIdentity.spec.js
            │   │   │   │   ├── reply.ts
            │   │   │   │   ├── requestDraft.ts
            │   │   │   │   ├── requestParticipantSuggestions.spec.ts
            │   │   │   │   ├── requestParticipantSuggestions.ts
            │   │   │   │   ├── saveDraft.ts
            │   │   │   │   └── sendDraft.ts
            │   │   │   ├── components/
            │   │   │   │   ├── AttachmentManager/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── Recipient/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── presenter.spec.jsx
            │   │   │   │   ├── RecipientList.scss
            │   │   │   │   ├── RecipientList.spec.tsx
            │   │   │   │   ├── RecipientList.tsx
            │   │   │   │   └── RecipientSelector.tsx
            │   │   │   ├── index.js
            │   │   │   ├── models.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── draft.ts
            │   │   │   ├── services/
            │   │   │   │   ├── calcSyncDraft.spec.ts
            │   │   │   │   ├── calcSyncDraft.ts
            │   │   │   │   ├── changeAuthorInParticipants.js
            │   │   │   │   ├── changeAuthorInParticipants.spec.js
            │   │   │   │   ├── filterIdentities.js
            │   │   │   │   ├── filterIdentities.spec.js
            │   │   │   │   ├── getIdentityProtocol.js
            │   │   │   │   ├── isValidRecipient.js
            │   │   │   │   ├── isValidRecipient.spec.js
            │   │   │   │   └── validate.ts
            │   │   │   └── types.d.ts
            │   │   ├── encryption/
            │   │   │   ├── actions/
            │   │   │   │   ├── decryptMessage.js
            │   │   │   │   ├── encryptMessage.js
            │   │   │   │   ├── fetchRemoteKeys.js
            │   │   │   │   └── getRecipientKeys.js
            │   │   │   ├── components/
            │   │   │   │   ├── AskPassphraseForm/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── CheckDecryption/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── LockedMessage/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   ├── message.ts
            │   │   │   │   └── publicKey.js
            │   │   │   └── services/
            │   │   │       └── keyring/
            │   │   │           └── remoteKeys.js
            │   │   ├── file/
            │   │   │   ├── actions/
            │   │   │   │   ├── deleteDraftAttachment.js
            │   │   │   │   └── uploadDraftAttachments.js
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       ├── index.js
            │   │   │       └── uploadFileAsFormField.js
            │   │   ├── form/
            │   │   │   ├── components/
            │   │   │   │   └── FormikPersist.tsx
            │   │   │   └── services/
            │   │   │       └── validators.ts
            │   │   ├── i18n/
            │   │   │   ├── components/
            │   │   │   │   └── I18nLoader.tsx
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       ├── getBestLocale.js
            │   │   │       ├── getLanguage.js
            │   │   │       └── getUserLocales.js
            │   │   ├── identity/
            │   │   │   ├── actions/
            │   │   │   │   ├── getIdentities.js
            │   │   │   │   ├── getLocalIdentities.js
            │   │   │   │   └── getRemoteIdentities.js
            │   │   │   ├── components/
            │   │   │   │   └── WithIdentities/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hoc/
            │   │   │   │   └── withIdentities.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useIdentities.ts
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   └── identitiesSelector.js
            │   │   │   ├── services/
            │   │   │   │   └── identityToParticipant.js
            │   │   │   └── types.d.ts
            │   │   ├── message/
            │   │   │   ├── actions/
            │   │   │   │   ├── createMessage.js
            │   │   │   │   ├── deleteMessage.js
            │   │   │   │   ├── fetchMessages.js
            │   │   │   │   ├── getDraft.spec.ts
            │   │   │   │   ├── getDraft.ts
            │   │   │   │   ├── getLastMessage.js
            │   │   │   │   ├── getLastMessage.spec.js
            │   │   │   │   ├── getMessage.js
            │   │   │   │   ├── getMessages.js
            │   │   │   │   ├── getParentMessage.js
            │   │   │   │   ├── requestDiscussion.js
            │   │   │   │   ├── requestMessages.js
            │   │   │   │   └── setMessageRead.js
            │   │   │   ├── components/
            │   │   │   │   └── ParticipantLabel/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useMessage.ts
            │   │   │   ├── index.js
            │   │   │   ├── models/
            │   │   │   │   ├── Message.ts
            │   │   │   │   └── Participant.ts
            │   │   │   ├── query.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── messageSelector.js
            │   │   │   ├── services/
            │   │   │   │   ├── findUserParticipant.js
            │   │   │   │   ├── findUserParticipant.spec.js
            │   │   │   │   ├── getLastMessageFromArray.js
            │   │   │   │   ├── isUserParticipant.js
            │   │   │   │   ├── isUserParticipant.spec.js
            │   │   │   │   └── sortMessages.js
            │   │   │   └── types.d.ts
            │   │   ├── notification/
            │   │   │   ├── components/
            │   │   │   │   ├── MessageNotificationHandler/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   └── NotificationProvider/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   └── messageNotificationsSelector.js
            │   │   │   └── services/
            │   │   │       └── notification.worker.js
            │   │   ├── pi/
            │   │   │   ├── components/
            │   │   │   │   ├── BackgroundImage/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── o-background-image.scss
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MultidimensionalPi/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PiGraph/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PiScore/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   └── Ratings/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.jsx
            │   │   │   ├── services/
            │   │   │   │   ├── pi/
            │   │   │   │   │   ├── index.spec.ts
            │   │   │   │   │   └── index.ts
            │   │   │   │   └── svg/
            │   │   │   │       ├── index.js
            │   │   │   │       └── index.spec.jsx
            │   │   │   └── types.d.ts
            │   │   ├── publicKey/
            │   │   │   ├── actions/
            │   │   │   │   ├── saveUserPublicKeyAction.js
            │   │   │   │   └── updatePublicKey.js
            │   │   │   └── index.js
            │   │   ├── pwa/
            │   │   │   ├── components/
            │   │   │   │   ├── InstallPromptConsumer.tsx
            │   │   │   │   └── InstallPromptProvider.tsx
            │   │   │   ├── contexts/
            │   │   │   │   └── InstallPromptContext.ts
            │   │   │   └── index.js
            │   │   ├── remoteIdentity/
            │   │   │   ├── actions/
            │   │   │   │   ├── createIdentity.js
            │   │   │   │   ├── deleteIdentity.js
            │   │   │   │   └── updateIdentity.js
            │   │   │   ├── components/
            │   │   │   │   ├── ProviderIcon/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── WithProviders/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hoc/
            │   │   │   │   ├── withAuthorize.jsx
            │   │   │   │   ├── withAuthorizePopup.jsx
            │   │   │   │   └── withProviders.jsx
            │   │   │   ├── index.js
            │   │   │   ├── model/
            │   │   │   │   └── Identity.js
            │   │   │   ├── selectors/
            │   │   │   │   ├── identitiesSelector.js
            │   │   │   │   ├── identitySelector.js
            │   │   │   │   └── identityStateSelector.js
            │   │   │   └── services/
            │   │   │       └── getProvider.js
            │   │   ├── routing/
            │   │   │   ├── components/
            │   │   │   │   ├── AuthenticatedLayout/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── withAuthenticatedProps.jsx
            │   │   │   │   ├── RoutingConsumer.jsx
            │   │   │   │   ├── RoutingProvider.jsx
            │   │   │   │   └── SwitchWithRoutes/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── index.spec.jsx
            │   │   │   ├── contexts/
            │   │   │   │   └── RoutingContext.js
            │   │   │   ├── hoc/
            │   │   │   │   ├── withPush.jsx
            │   │   │   │   ├── withReplace.jsx
            │   │   │   │   ├── withRouteParams.jsx
            │   │   │   │   └── withSearchParams.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useSearchParams.ts
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       ├── findTabbableRouteConfig.js
            │   │   │       ├── flattenRouteConfig.js
            │   │   │       ├── flattenRouteConfig.spec.jsx
            │   │   │       ├── getRouterHistory.js
            │   │   │       ├── getSearchParams.spec.ts
            │   │   │       ├── getSearchParams.ts
            │   │   │       ├── signout.js
            │   │   │       └── url/
            │   │   │           ├── CrappyURLSearchParams.js
            │   │   │           ├── CrappyURLSearchParams.spec.js
            │   │   │           ├── QueryStringSerializer.js
            │   │   │           ├── buildURL.js
            │   │   │           └── index.js
            │   │   ├── scroll/
            │   │   │   ├── components/
            │   │   │   │   └── ScrollDetector/
            │   │   │   │       ├── index.js
            │   │   │   │       └── index.js.w_detection
            │   │   │   ├── hoc/
            │   │   │   │   ├── withScrollManager.jsx
            │   │   │   │   └── withScrollTarget.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useScrollToMe.ts
            │   │   │   ├── index.js
            │   │   │   ├── services/
            │   │   │   │   ├── getTop.js
            │   │   │   │   ├── getViewPortTop.js
            │   │   │   │   └── scrollTop.js
            │   │   │   └── vendors/
            │   │   │       └── scroll-doc.js
            │   │   ├── search/
            │   │   │   ├── components/
            │   │   │   │   └── SearchField/
            │   │   │   │       ├── index.js
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   └── index.js
            │   │   ├── settings/
            │   │   │   ├── components/
            │   │   │   │   └── WithSettings/
            │   │   │   │       ├── index.js
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── presenter.spec.jsx
            │   │   │   ├── hoc/
            │   │   │   │   └── withSettings.js
            │   │   │   ├── hooks/
            │   │   │   │   └── useSettings.ts
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   └── settings.ts
            │   │   │   ├── services/
            │   │   │   │   └── getDefaultSettings/
            │   │   │   │       └── index.js
            │   │   │   └── types.d.ts
            │   │   ├── tab/
            │   │   │   ├── components/
            │   │   │   │   ├── TabConsumer/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   └── TabProvider/
            │   │   │   │       └── index.jsx
            │   │   │   ├── contexts/
            │   │   │   │   └── TabContext.js
            │   │   │   ├── hoc/
            │   │   │   │   ├── withCloseTab.jsx
            │   │   │   │   ├── withCurrentTab.jsx
            │   │   │   │   └── withUpdateTab.jsx
            │   │   │   ├── hooks/
            │   │   │   │   ├── useCloseTab.ts
            │   │   │   │   └── useCurentTab.ts
            │   │   │   ├── index.js
            │   │   │   ├── model/
            │   │   │   │   └── Tab.js
            │   │   │   └── services/
            │   │   │       └── getTabUrl.js
            │   │   ├── tags/
            │   │   │   ├── components/
            │   │   │   │   ├── ManageEntityTags.spec.tsx
            │   │   │   │   ├── ManageEntityTags.tsx
            │   │   │   │   ├── TagFieldGroup/
            │   │   │   │   │   ├── index.spec.jsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── TagItem/
            │   │   │   │   │   ├── __snapshots__/
            │   │   │   │   │   │   └── index.spec.tsx.snap
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TagsForm/
            │   │   │   │       ├── index.spec.tsx
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── hoc/
            │   │   │   │   └── withTags/
            │   │   │   │       └── index.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useTags.ts
            │   │   │   ├── index.ts
            │   │   │   ├── query.ts
            │   │   │   ├── services/
            │   │   │   │   ├── getTagLabel/
            │   │   │   │   │   ├── index.spec.ts
            │   │   │   │   │   └── index.ts
            │   │   │   │   ├── getTagNamesInCommon.spec.ts
            │   │   │   │   ├── getTagNamesInCommon.ts
            │   │   │   │   ├── searchTags.spec.ts
            │   │   │   │   └── searchTags.ts
            │   │   │   ├── store/
            │   │   │   │   ├── index.ts
            │   │   │   │   ├── reducer.ts
            │   │   │   │   └── selectors.ts
            │   │   │   └── types.d.ts
            │   │   ├── user/
            │   │   │   ├── actions/
            │   │   │   │   └── getUser.js
            │   │   │   ├── components/
            │   │   │   │   ├── SigninForm/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   └── SubmitButton.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── SignupForm/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   └── PiwikModal.tsx
            │   │   │   │   │   ├── form-validator.spec.ts
            │   │   │   │   │   ├── form-validator.ts
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── UserInfo/
            │   │   │   │   │   ├── UserInfo.spec.tsx
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── UserMenu/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── next-feature-button.scss
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   ├── presenter.spec.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── WithUser/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hoc/
            │   │   │   │   └── withUser.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useUser.ts
            │   │   │   ├── index.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── userSelector.ts
            │   │   │   ├── services/
            │   │   │   │   ├── deleteUser.js
            │   │   │   │   ├── isAuthenticated/
            │   │   │   │   │   └── index.js
            │   │   │   │   ├── signup/
            │   │   │   │   │   └── index.js
            │   │   │   │   └── usernameNormalizer/
            │   │   │   │       └── index.js
            │   │   │   ├── store/
            │   │   │   │   ├── index.ts
            │   │   │   │   ├── reducer.ts
            │   │   │   │   └── selectors.ts
            │   │   │   └── types.d.ts
            │   │   ├── userNotify/
            │   │   │   ├── actions/
            │   │   │   │   └── notify.js
            │   │   │   ├── hoc/
            │   │   │   │   └── withNotification.jsx
            │   │   │   └── index.js
            │   │   └── view/
            │   │       ├── actions/
            │   │       │   └── requestMessages.js
            │   │       ├── components/
            │   │       │   └── WithViewModel/
            │   │       │       └── index.jsx
            │   │       ├── config.js
            │   │       ├── index.js
            │   │       ├── models/
            │   │       │   └── View.js
            │   │       └── selectors/
            │   │           └── viewSelector.js
            │   ├── scenes/
            │   │   ├── About/
            │   │   │   ├── components/
            │   │   │   │   └── StylezedScreenshot/
            │   │   │   │       └── index.tsx
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── ApplicationSettings/
            │   │   │   ├── components/
            │   │   │   │   ├── ContactSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   ├── DesktopNotificationSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── InterfaceSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   ├── MessageSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   └── NotificationSettings/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── ContactAssociation/
            │   │   │   ├── contact-association.scss
            │   │   │   ├── index.spec.tsx
            │   │   │   └── index.tsx
            │   │   ├── DevicesSettings/
            │   │   │   ├── components/
            │   │   │   │   ├── DeviceForm/
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── DeviceInformation/
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── DeviceSettings/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── RevokeDevice/
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── VerifyDevice/
            │   │   │   │       ├── index.spec.tsx
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Discussion/
            │   │   │   ├── components/
            │   │   │   │   ├── AddParticipantsToContactBook/
            │   │   │   │   │   ├── add-participants-dropdown.scss
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── DownloadFileProgression/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── InstantMessage/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   ├── instant-message-aside.scss
            │   │   │   │   │   ├── instant-message-author.scss
            │   │   │   │   │   ├── instant-message-participants.scss
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MailMessage/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   ├── mail-message-details.scss
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── Message.tsx
            │   │   │   │   ├── MessageAttachments/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MessageList/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MessagePi/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MessageRecipients.tsx
            │   │   │   │   ├── ProtocolSwitch/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── QuickDraftForm/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   └── ToggleAdvancedFormButton/
            │   │   │   │   │   │       ├── index.jsx
            │   │   │   │   │   │       └── toggle-advanced-draft-button.scss
            │   │   │   │   │   ├── draft-message-quick.scss
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── ReplyExcerpt/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TagList/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── discussion-action-bar.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   ├── style.scss
            │   │   │   └── types.d.ts
            │   │   ├── ForgotPassword/
            │   │   │   ├── components/
            │   │   │   │   └── ForgotPasswordForm/
            │   │   │   │       ├── index.jsx
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── presenter.spec.jsx
            │   │   ├── NewDeviceInfo/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── NewDraft/
            │   │   │   ├── components/
            │   │   │   │   ├── DraftDiscussion/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── useDraftDiscussion.tsx
            │   │   │   │   └── DraftMessage/
            │   │   │   │       ├── components/
            │   │   │   │       │   ├── IdentitySelector.tsx
            │   │   │   │       │   └── Recipients.tsx
            │   │   │   │       ├── draft-message-advanced.scss
            │   │   │   │       ├── draft-message-placeholder.scss
            │   │   │   │       └── index.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── RemoteIdentitySettings/
            │   │   │   ├── components/
            │   │   │   │   ├── AuthButton/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── LastConnection/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── NewIdentity/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── new-identity.scss
            │   │   │   │   │   ├── provider-email-button.scss
            │   │   │   │   │   └── provider-list.scss
            │   │   │   │   ├── ProviderButton/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ProviderButtonContainer/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── RemoteIdentity/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── RemoteIdentityDetails/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── RemoteIdentityEmail/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── index.spec.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── RemoteIdentityOauth/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   └── Status/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── ResetPassword/
            │   │   │   ├── components/
            │   │   │   │   └── ResetPasswordForm/
            │   │   │   │       ├── index.jsx
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── presenter.spec.jsx
            │   │   ├── SearchResults/
            │   │   │   ├── components/
            │   │   │   │   ├── ContactResultItem/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── Highlights/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── index.spec.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── MessageResultItem/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── SettingsSignatures/
            │   │   │   ├── components/
            │   │   │   │   └── SignatureForm/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── Signin.tsx
            │   │   ├── Signup.tsx
            │   │   ├── TagsSettings/
            │   │   │   ├── components/
            │   │   │   │   ├── TagInput/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TagSearch/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Timeline/
            │   │   │   ├── components/
            │   │   │   │   ├── DiscussionItem/
            │   │   │   │   │   ├── discussion-item-content.scss
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── DiscussionSelector/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   ├── style.scss
            │   │   │   └── timeline-action-bar.scss
            │   │   ├── UserPrivacy/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── UserProfile/
            │   │   │   ├── components/
            │   │   │   │   ├── ProfileForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── ProfileInfo/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── UserSecurity/
            │   │   │   ├── components/
            │   │   │   │   ├── LoginDetails/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── OpenPGPForm.scss
            │   │   │   │   ├── OpenPGPGenerateForm.tsx
            │   │   │   │   ├── OpenPGPImportForm.tsx
            │   │   │   │   ├── OpenPGPKey/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── OpenPGPPrivateKeys/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PasswordDetails/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PasswordForm/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TFAForm/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── ValidateDevice/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── View/
            │   │   │   ├── components/
            │   │   │   │   ├── MessageItem/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── MessageSelector/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.jsx
            │   │   │   ├── style.scss
            │   │   │   └── withCurrentView.jsx
            │   │   ├── contact/
            │   │   │   ├── Contact.tsx
            │   │   │   ├── ContactBook/
            │   │   │   │   ├── components/
            │   │   │   │   │   ├── ImportContact/
            │   │   │   │   │   │   ├── index.js
            │   │   │   │   │   │   └── presenter.jsx
            │   │   │   │   │   ├── ImportContactButton/
            │   │   │   │   │   │   └── index.tsx
            │   │   │   │   │   ├── ImportContactForm/
            │   │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   │   └── style.scss
            │   │   │   │   │   └── TagList/
            │   │   │   │   │       ├── index.tsx
            │   │   │   │   │       └── style.scss
            │   │   │   │   ├── contact-book-menu.scss
            │   │   │   │   ├── index.spec.tsx
            │   │   │   │   ├── index.tsx
            │   │   │   │   ├── query.spec.tsx
            │   │   │   │   ├── query.ts
            │   │   │   │   └── style.scss
            │   │   │   ├── ContactForm.tsx
            │   │   │   ├── EditContact.spec.tsx
            │   │   │   ├── EditContact.tsx
            │   │   │   ├── NewContact.spec.tsx
            │   │   │   ├── NewContact.tsx
            │   │   │   ├── components/
            │   │   │   │   ├── AddFormFieldForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── AddressDetails/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── AddressForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── BirthdayDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── BirthdayForm/
            │   │   │   │   │   ├── index.ts
            │   │   │   │   │   └── presenter.tsx
            │   │   │   │   ├── ContactPageWrapper.tsx
            │   │   │   │   ├── ContactProfileForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ContactTitleField/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── EmailDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── EmailForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── FormCollection/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── IdentityDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── IdentityForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ImDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── ImForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── OrgaDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── OrgaForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PhoneDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── PhoneForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PublicKeyForm/
            │   │   │   │   │   ├── index.ts
            │   │   │   │   │   ├── presenter.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PublicKeyList/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── ReduxedInputFileGroup/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── contact-action-bar.scss
            │   │   │   ├── contact-main-title.scss
            │   │   │   ├── services/
            │   │   │   │   ├── contactValidation.jsx
            │   │   │   │   ├── contactValidation.spec.jsx
            │   │   │   │   ├── handleContactSaveErrors.spec.ts
            │   │   │   │   └── handleContactSaveErrors.ts
            │   │   │   └── style.scss
            │   │   └── error/
            │   │       ├── PageError.tsx
            │   │       ├── PageNotFound.tsx
            │   │       ├── components/
            │   │       │   └── CaliopenAscii.tsx
            │   │       └── style.scss
            │   ├── services/
            │   │   ├── api-client/
            │   │   │   ├── index.ts
            │   │   │   └── types.d.ts
            │   │   ├── api-location/
            │   │   │   └── index.js
            │   │   ├── api-patch/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── asciify.js
            │   │   ├── asciify.spec.js
            │   │   ├── browser-notification/
            │   │   │   └── index.js
            │   │   ├── capitalize.js
            │   │   ├── config.ts
            │   │   ├── encode-utils/
            │   │   │   ├── index.js
            │   │   │   └── utf8ArrayToString.js
            │   │   ├── encryption/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── event-manager/
            │   │   │   └── index.js
            │   │   ├── filter-contacts/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── importance-level/
            │   │   │   └── index.js
            │   │   ├── localStorage/
            │   │   │   └── index.js
            │   │   ├── message/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── mime/
            │   │   │   └── index.js
            │   │   ├── openpgp-keychain-repository/
            │   │   │   └── index.js
            │   │   ├── openpgp-manager/
            │   │   │   ├── api.ts
            │   │   │   ├── errors.ts
            │   │   │   ├── index.spec.ts
            │   │   │   └── index.ts
            │   │   ├── protocols-config/
            │   │   │   └── index.ts
            │   │   ├── renderReduxField/
            │   │   │   └── index.jsx
            │   │   └── username-utils/
            │   │       ├── username-availability.ts
            │   │       ├── username-validity.spec.ts
            │   │       └── username-validity.ts
            │   ├── store/
            │   │   ├── actions/
            │   │   │   ├── message.js
            │   │   │   └── timeline.js
            │   │   ├── configure-store.ts
            │   │   ├── middlewares/
            │   │   │   ├── axios-middleware.ts
            │   │   │   ├── crash-reporter-middleware.js
            │   │   │   ├── decryption-middleware.js
            │   │   │   ├── discussions-middleware.js
            │   │   │   ├── encryption-middleware.js
            │   │   │   ├── freeze.js
            │   │   │   ├── importance-level-middleware.js
            │   │   │   ├── messages-middleware.js
            │   │   │   └── search-middleware.js
            │   │   ├── modules/
            │   │   │   ├── device.ts
            │   │   │   ├── discussion.ts
            │   │   │   ├── draft-message.spec.ts
            │   │   │   ├── draft-message.ts
            │   │   │   ├── encryption.ts
            │   │   │   ├── i18n.js
            │   │   │   ├── importance-level.js
            │   │   │   ├── local-identity.js
            │   │   │   ├── message.js
            │   │   │   ├── message.spec.js
            │   │   │   ├── notification.js
            │   │   │   ├── participant-suggestions.ts
            │   │   │   ├── provider.js
            │   │   │   ├── public-key.js
            │   │   │   ├── remote-identity.js
            │   │   │   ├── search.js
            │   │   │   ├── settings.js
            │   │   │   └── view.js
            │   │   ├── reducer.ts
            │   │   └── selectors/
            │   │       ├── device.js
            │   │       ├── getModuleStateSelector.js
            │   │       ├── message.js
            │   │       ├── provider.js
            │   │       ├── settings.js
            │   │       ├── tab.js
            │   │       └── timeline.js
            │   ├── styles/
            │   │   ├── base/
            │   │   │   ├── fonts.scss
            │   │   │   └── reset.scss
            │   │   ├── common.scss
            │   │   ├── config/
            │   │   │   ├── config.scss
            │   │   │   └── theme/
            │   │   │       ├── dark.scss
            │   │   │       └── light.scss
            │   │   ├── object/
            │   │   │   ├── o-avatar.scss
            │   │   │   ├── o-callout.scss
            │   │   │   ├── o-clickable.scss
            │   │   │   ├── o-date-picker.scss
            │   │   │   ├── o-form-element.scss
            │   │   │   ├── o-hidden-element.scss
            │   │   │   ├── o-navigation.scss
            │   │   │   ├── o-pi-border.scss
            │   │   │   ├── o-reset-html-message.scss
            │   │   │   └── o-triangle.scss
            │   │   ├── util/
            │   │   │   ├── breakpoint.scss
            │   │   │   ├── flex-grid.scss
            │   │   │   └── u-gradient.scss
            │   │   └── vendor/
            │   │       ├── bootstrap_font-awesome.scss
            │   │       ├── bootstrap_foundation-sites.scss
            │   │       ├── bootstrap_react-redux-notify.scss
            │   │       └── foundation-sites/
            │   │           ├── _config.scss
            │   │           └── _flex-grid.scss
            │   └── types.d.ts
            ├── template/
            │   ├── index.ejs
            │   └── index.html
            ├── test/
            │   ├── fixtures/
            │   │   ├── contacts/
            │   │   │   ├── data.json
            │   │   │   └── index.ts
            │   │   ├── device/
            │   │   │   └── index.ts
            │   │   ├── tags/
            │   │   │   └── data.json
            │   │   └── user/
            │   │       ├── data.json
            │   │       └── index.ts
            │   ├── functional/
            │   │   ├── features/
            │   │   │   ├── 00_home-spec.js
            │   │   │   ├── 10_discussion-spec.js
            │   │   │   ├── 20-message-list-spec.js
            │   │   │   ├── 21-reply-to-messag-spec.js
            │   │   │   ├── 22-compose-spec.js
            │   │   │   ├── 23-delete-message-spec.js
            │   │   │   ├── 24-scroll-spec.js
            │   │   │   ├── 25-assoc-participant-contact-spec.js
            │   │   │   ├── 30-settings-spec.js
            │   │   │   ├── 35-remote-identitiy-settings-spec.js
            │   │   │   ├── 40-new-contact-spec.js
            │   │   │   ├── 50-search-spec.js
            │   │   │   ├── 60-tag-spec.js
            │   │   │   ├── 70-device-spec.js
            │   │   │   ├── 80-account-spec.js
            │   │   │   └── 90_notification-spec.js
            │   │   ├── protractor.conf.js
            │   │   └── utils/
            │   │       ├── navigation.js
            │   │       ├── timeline.js
            │   │       ├── user-util.js
            │   │       └── window.js
            │   ├── msw-handlers/
            │   │   ├── contacts.ts
            │   │   ├── settings.ts
            │   │   ├── tags.ts
            │   │   └── user.ts
            │   ├── providers.tsx
            │   ├── server.ts
            │   └── unit/
            │       ├── lingui-react.jsx
            │       └── setup.ts
            ├── tsconfig.json
            └── webpack/
                ├── config.js
                ├── webpack.common.js
                ├── webpack.config.browser.js
                └── webpack.config.server.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .drone.yml
================================================
workspace:
  base: /srv
  path: caliopen

clone:
  git:
    image: plugins/git
    depth: 10
    recursive: false

pipeline:

##################################
##          BASE IMAGES         ##
##################################

  build-caliopen-go:
    group: build0
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - DEPS=vendor
      - BASE_DIR=src/backend
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.caliopen-go
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_go
    when:
      branch: [ develop, master ]
      event: [ push ]
    commands:
      - . devtools/drone/files_changed.sh
      - . devtools/drone/build_images.sh

#######################################################
##          TEST ON MASTER OR DEVELOP PR             ##
#######################################################

  test-go:
    group: test
    pull: true
    image: public-registry.caliopen.org/caliopen_go
    environment:
      - BASE_DIR=/go/src/github.com/CaliOpen/Caliopen/src/backend
    when:
      branch: [ develop ]
      event: [ pull_request ]
    commands:
      - cp -r /srv/caliopen/src/backend/* $${BASE_DIR}
      - cd $${BASE_DIR} && govendor sync -v
      - go test ./...

  test-py:
    pull: true
    group: test
    image: public-registry.caliopen.org/caliopen_python
    environment:
      - CALIOPEN_BASEDIR=/srv/caliopen
      - BASE_DIR=src/backend
    when:
      branch: [ develop, master ]
      event: [ pull_request ]
    commands:
      - . devtools/drone/files_changed.sh
      - . devtools/drone/test_py.sh

  test-frontend:
    group: test
    image: node:16
    when:
      branch: [ develop, master ]
      event: [ pull_request ]
    environment:
      - BASE_DIR=src/frontend
    commands:
      - . devtools/drone/files_changed.sh
      - . devtools/drone/test_front.sh

#########################################################
##          BUILD AND PUBLISH ON DEVELOP PUSH          ##
#########################################################

  # Python develop images
  build-py-cli-develop:
    group: build1
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.cli
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_cli
      - BASE_DIR=src/backend
      - LANG=python
      - PROG=tools/py.CLI
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/get_py_dependencies.sh # Get the list of dependencies
      - . devtools/drone/files_changed.sh # Check if any file has been modified
      - . devtools/drone/build_images.sh # Build docker image

  build-apiv1-develop:
    group: build1
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.py-api
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_apiv1
      - BASE_DIR=src/backend
      - LANG=python
      - PROG=interfaces/REST/py.server
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/get_py_dependencies.sh # Get the list of dependencies
      - . devtools/drone/files_changed.sh # Check if any file has been modified
      - . devtools/drone/build_images.sh # Build docker image

  build-mq-worker-develop:
    group: build1
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.mq-worker
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_mqworker
      - BASE_DIR=src/backend
      - LANG=python
      - PROG=interfaces/NATS/py.client
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/get_py_dependencies.sh # Get the list of dependencies
      - . devtools/drone/files_changed.sh # Check if any file has been modified
      - . devtools/drone/build_images.sh # Build docker image

  ## GO develop images
  build-apiv2-develop:
    group: build2
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.go-api
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_apiv2
      - PROG=interfaces/REST/go.server/cmd/caliopen_rest
      - BASE_DIR=src/backend
      - LANG=go
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/get_go_dependencies.sh
      - . devtools/drone/files_changed.sh
      - . devtools/drone/build_images.sh

  build-lmtpd-develop:
    group: build2
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.go-lmtp
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_lmtpd
      - PROG=protocols/go.smtp/cmd/caliopen_lmtpd
      - BASE_DIR=src/backend
      - LANG=go
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/get_go_dependencies.sh
      - . devtools/drone/files_changed.sh
      - . devtools/drone/build_images.sh

  build-idpoller-develop:
    group: build2
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.identity-poller
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_identitypoller
      - PROG=workers/go.remoteIDs/cmd/idpoller
      - BASE_DIR=src/backend
      - LANG=go
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/get_go_dependencies.sh
      - . devtools/drone/files_changed.sh
      - . devtools/drone/build_images.sh

  build-imapworker-develop:
    group: build2
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
      - PLUGIN_DOCKERFILE=src/backend/Dockerfile.imap-worker
      - PLUGIN_CONTEXT=/srv/caliopen/src/backend
      - PLUGIN_REPO=registry.caliopen.org/caliopen_imapworker
      - PROG=protocols/go.imap/cmd/imapworker
      - BASE_DIR=src/backend
      - LANG=go
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/get_go_dependencies.sh
      - . devtools/drone/files_changed.sh
      - . devtools/drone/build_images.sh

  build-twitterworker-develop:
    group: build2
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY]
    environment:
    - PLUGIN_DOCKERFILE=src/backend/Dockerfile.twitter-worker
    - PLUGIN_CONTEXT=/srv/caliopen/src/backend
    - PLUGIN_REPO=registry.caliopen.org/caliopen_twitterworker
    - PROG=protocols/go.twitter/cmd/twitterworker
    - BASE_DIR=src/backend
    - LANG=go
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
    - export PLUGIN_TAGS=develop
    - . devtools/drone/get_go_dependencies.sh
    - . devtools/drone/files_changed.sh
    - . devtools/drone/build_images.sh

  build-frontend-develop:
    group: build3
    image: public-registry.caliopen.org/caliopen_drone_docker
    privileged: true
    secrets: [ DOCKER_USERNAME , DOCKER_PASSWORD, DOCKER_REGISTRY ]
    environment:
      - PLUGIN_DOCKERFILE=src/frontend/web_application/Dockerfile
      - PLUGIN_CONTEXT=/srv/caliopen/src/frontend/web_application
      - PLUGIN_REPO=registry.caliopen.org/caliopen_frontend
      - BASE_DIR=src/frontend/web_application
      - LANG=js
    when:
      branch: [ develop ]
      event: [ push ]
    commands:
      - export PLUGIN_TAGS=develop
      - . devtools/drone/files_changed.sh
      - . devtools/drone/build_images.sh

#########################################################
##          BUILD AND PUBLISH ON TAG: RELEASE-         ##
#########################################################

  build-py-cli-release:
    group: release1
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.cli
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_cli
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

  build-apiv1-release:
    group: release1
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.py-api
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_apiv1
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

  build-mq-worker-release:
    group: release1
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.mq-worker
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_mqworker
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

  build-apiv2-release:
    group: release2
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.go-api
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_apiv2
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

  build-lmtpd-release:
    group: release2
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.go-lmtp
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_lmtpd
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

  build-idpoller-release:
    group: release2
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.identity-poller
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_identitypoller
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

  build-imapworker-release:
    group: release2
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.imap-worker
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_imapworker
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

  build-twitterworker-release:
    group: release2
    image: plugins/docker
    dockerfile: src/backend/Dockerfile.twitter-worker
    context: /srv/caliopen/src/backend
    repo: registry.caliopen.org/caliopen_twitterworker
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
    - latest
    - ${DRONE_TAG##release-}

  build-frontend-release:
    group: release3
    image: plugins/docker
    dockerfile: src/frontend/web_application/Dockerfile
    context: /srv/caliopen/src/frontend/web_application
    repo: registry.caliopen.org/caliopen_frontend
    secrets: [ DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY ]
    when:
      ref: [ "refs/tags/release-*" ]
      event: [ tag ]
    tags:
      - latest
      - ${DRONE_TAG##release-}

#########################################################
##                     SERVICES                        ##
#########################################################


================================================
FILE: .git-crypt/.gitattributes
================================================
# Do not edit this file.  To specify the files to encrypt, create your own
# .gitattributes file in the directory where your files are.
* !filter !diff
*.gpg binary


================================================
FILE: .gitattributes
================================================
devtools/kubernetes/secrets/*.yaml filter=git-crypt diff=git-crypt


================================================
FILE: .gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml

# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml

# Gradle:
.idea/gradle.xml
.idea/libraries

# Mongo Explorer plugin:
.idea/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### VirtualEnv template
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Ii]nclude
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
venv/
ENV/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject
/.idea/
*.iml

# vagrant directory
.vagrant

# Docker data
.data

# Golang
src/backend/**/vendor/**/

# Node
node_modules

# private fixtures
/devtools/email-with-parts-and-attachments

# registry configuration
/devtools/registry.conf


================================================
FILE: .travis.yml
================================================
sudo: required
services:
- docker
env:
  COMPOSE_VERSION: 1.9.0
language: node_js
node_js:
- '8'
cache:
  - yarn
git:
  depth: 10
before_install:
- curl -L https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-`uname
  -s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH="$HOME/.yarn/bin:$PATH"
before_script:
  - git fetch origin $TRAVIS_BRANCH:$TRAVIS_BRANCH
script:
- devtools/run-tests.sh
notifications:
  irc:
    channels:
      - "chat.freenode.net#caliopdev"


================================================
FILE: CHANGELOG.md
================================================
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.27.1] 2023-05-09

### Fixed

- JS error when saving settings.

## [0.27.0] 2023-05-05

### Changed

- CLI commands `resync_shard` and `resync_index` does not stop when an error
  occured.

## [0.26.1] 2023-05-03

### Fixed

- Empty discussion list.

## [0.26.0] 2023-04-04

### Changed

- Replace PI message illustration by a PI score (A to E).

## [0.25.3] 2023-02-28

### Fixed

- Improve device management frontend codebase

## [0.25.2] 2023-01-25

### Fixed

- Handle username availability errors on the client.
- Remove unexpected errors on login page on first display.

## [0.25.1] 2023-01-12

### Fixed

- Update client's dependencies.
- Load locale at run time on the client.
- Small improvements in tag managements & Contact book.

## [0.25.0] 2022-03-03

### Change

- Improve contact edit form. Better error handling.

## [0.24.6] 2021-10-23

### Fixed

- Unable to to delete account.

## [0.24.5] 2021-08-20

### Fixed

- Crash after signup, use a subquery instead.

### Changed

- Redirect to external account configuration after signup.

## [0.24.4] 2021-07-25

### Fixed

- Advanced draft suggestions correctly displayed.
- Color of signin & signup spinner button set to bright.

## [0.24.3] 2021-06-14

### Fixed

- Unable to quick reply to a mastodon or tweeter dm

## [0.24.2] 2021-06-11

### Fixed

- client BSOD: Make sure user is loaded before accessing to the contact.

## [0.24.1] 2021-06-09

### Fixed

- tag management
- login form
- Mastodon DM handling

## [0.24.0] 2021-03-02

### Changed

- re-enable Take a Tour.
- update internal frontend dependencies.
- Edit advanced draft in its specific page.
- update dependencies

### Fixed

- Openpgp form when only one identity.

## [0.23.1] 2019-09-17

### Fixed

- No feedbacks were displayed when errors happend on signin form.
- No spinner on activity on signin form.

## [0.23] 2019-07-19

### Added

- Mastodon protocol
- Tag email with imap flags when fetching external account

### Changed

- Better Timeline display for large and small screens.
- Batch notifications

### Fixed

- bugs in imap worker
- bugs in some responsiveness UI components
- username validation

## [0.22] 2019-06-26

## Added

- The new about landpage.

### Changed

- Upload PGP keys using files rather than textboxes.
- Notifications : output bach operations (external identities fetches for ex.)
  into one notification

### Fixed

- Double redirections algorithm client and server when not authenticated
- Prevent target blank anchor's xss.
- Reload devices when changing page or when invalidated.
- Page rendering after signout with unexpected content cached.
- username validation to conform more tightly to specifications.

## [0.21] 2019-06-06

### Added

- Always link participant to contact in a draft when contact exists (ensure
  message can be encrypted)
- Validate body cannot be empty for a Twitter DM.
- Upload user's public key when adding a private key.
- Discussion has unread message button.
- Dynamic contacts references embedded in messages

### Changed

- FTS and participants lookup improvments
- On quick reply, «Enter» will not send draft anymore, it must be CTRL+Enter.
- Quick reply is now multilines.
- Use message's excerpt in search results instead of garbled highlights
- Move vcard file import route on apiv2 to use contact uniqueness and lookups
  principles
- Re-enable import contacts via vcard file.
- New messages notification is not displayed anymore, it is now automatically
  loaded.
- Send button icon in advanced form.
- Disable «Take a tour» which is not working properly
- Disable the send button on quick draft when empty (thanks Sebbaz).
- Look and feel of GPG buttons which look like disabled.

### Fixed

- Default locale saved on account creation.
- Responsiveness for the «new device page».
- BSOD while including regexp special chars in search query.
- Email icon was always on Timeline.
- Contact starting w/ a letter with a diacritic is not displayed on ContactBook.
- Contacts list update after contact deletion
- Twitter workers errors handling
- Imap workers errors handling
- Messages' excerpts showing html tags
- BSOD when changing identity in draft when no recipients (thanks peha)
- Many encoding issues during mail delivery
- Participants algorithm edge case
- Discussion last message sort better
- Index user contact without alias using a workaround to bad core/mixin classes
  design
- Addresses emails parsing failed sometimes with strange values
- Process better invalid or missing data and encoding problems in incoming
  message
- Signout wasn't effective

## [0.20.0] 2019-05-15

### Added

- Validation of twitter username in contact edition
- Address (and protocol) selection in a 1-to-1 discussion
- Activate links in plain text messages.
- Handle client crashes and provide a link to report an issue on
  https://feedback.caliopen.org

### Changed

- Disable draft form in case there is no selected identity
- Facebook username is no more available in contact edition
- In a draft, switch identity will change the protocol of all recipients as well
- Disable contact import
- Do not display private key details, allow "download" instead.
- Providers buttons are available according to backend configuration (api:
  `/api/v2/providers`)

### Fixed

- Simple detection of PGP inline message
- Apiv2 create and delete contacts does not use `user.shard_id`
- Better logging for apiv2 and mq-worker
- Do not fail if ContactLookup raise a NotFound
- Twitter nick not displayed on contact book
- Select Twitter identity according to parent message on a new draft
- Show at least 1 participant per discussion on timeline
- Send a quick draft by pressing «Enter» and display a spinner

## [0.18.2] 2019-04-26

### Fixed

- signup does not authenticate and crash
- hardcoded references to "alpha.caliopen.org" in client

## [0.18.1] 2019-04-26

### Changed

- Better display of message's participants
- Fix attachment visibility
- Raise an explicit error on duplicate message for better processing
- Validate better email address when cleaning it
- Better oauth token validation

### Fixed

- Attachments visibility, it displays a warning if the message has been
  encrypted

## [0.18.0] 2019-04-23

### Fixed

- render form after draft deletion
- Reply encrypted messages
- Hide "load" more button when all messages are displayed
- Display decryption error message
- Glitches on encrypted mails
- Display facebook names on contact book

### Added

- Send and receive text/plain MIME messages
- Show full date on Hover
- Suggest Twitter handles in draft form

## [0.17.0] 2019-03-21

### Added

- End to end PGP encryption/decryption.
- When user adds an external account, external identity is added to user's
  contact card
- Test for imap worker, twitter worker and identities worker
- Actions for instant messages (delete, reply …) and tag list where missing
- PWA: add to home screen
- PWA: basic offline capabilities
- Search when click on tags (basic search)
- Verify device by mail

### Fixed

- Fix chronological order of messages in discussion scene
- Better responsiveness on small screens for timeline & discussion & logo
- Better responsiveness on small screens for dropdowns
- inversion en/fr for some translations
- BSOD on draft view in case there is no author (for example after remote
  identity deletion)
- Last messages not visible in case the discussion has been openned
- Sync contact associated to the user when editing in the contact book
- Accept only Private Key in user account

### Changed

- Remove device's locations field (IP definition) that wasn't saved and has no
  effects for now

## [0.16.0] 2019-02-25

### Added

- Handle lost authentication, redirect signin
- A simple view with draft messages
- Display the discussion related to the selected participants of a draft
- Compute an experimental different PI structure for message entity
- A caliopen_data python package for caliopen data manipulation
- A machine learning model for message automatic tagging
- Create an RFC 3156 compatible mime structure for PGP encrypted sent email
- Add an API route to find if a discussion exist for a list of participants
- Ignore already imported message

### Changed

- Move link external accounts to user menu
- Smaller font for desktop
- Use white color for plain text buttons
- Refactor hover and active colors for buttons
- Display a progress bar when downloading an attachment
- New calcul for Privacy Index
- Take A Tour has been moved in the new menu «Help & Info»
- Display related emails for a PGP public key
- Compute related discussion only when the message is sent
- Better discussion match if any participant is a known contact
- Reworked deeply job dispatching logic for protocol workers

### Fixed

- Bad redirection when canceling contact creation
- Add spaces between buttons in contact edit & contact association pages
- Unable to download an attachment due to missing request's headers

## [0.15.2] 2019-01-23

### Fixed

- Many fixes on remote identities workers (imap, twitter) tested on production

## [0.15.1] 2019-01-22

### Fixed

- BSOD on discussion when contacts not yet loaded

## [0.15.0] 2019-01-15

### Added

- When an user authenticate we issue a device.login event
- Add a contact from a discussion
- Privacy Policy page available at
  https://alpha.caliopen.org/privacy-policy.html

### Fixed

- typos on English catalog (thanks octplane)
- Existing device are found better, lead to less untrusted device for user
- Click on contact's title "input" submits the form
- Empty contact book even when user has a contact (always actually)
- Route /discussion/{discussion_id} to retrieve one discussion
- `unread_count` in discussions list

### Changed

- Rework how privacy features are declared and managed
- Change how a discussion hash is build, take contact_id as better key

## [0.14.0] 2018-12-19

### Added

- special group user contact in contact-book
- Toggle show spam
- Placeholder when loading Timeline
- Messages de-duplication when importing or re-importing from external accounts

### Fixed

- Timeline responsiveness (dates & action bar)
- Display last protocol used for a discussion in the timeline
- Automatic set read when displaying a message
- participants added from suggestions always define `email` protocol
- More permissive protocol validation in draft according to identities

### Changed

- Timeline colors

## [0.13.2] 2018-12-11

### Added

- Switch identity, send twitter DM, validation…
- Support new dm twitter notification

### Fixed

- Crash when replying a message.
- Help button has no effects
- Unable to change password
- Better layout for twitter DM
- Avatar size in tabs for twitter DM
- Splash screen initialization after reconnect

## [0.13.1] 2018-12-05

### Fixed

- BSOD when selecting contact
- All messages detected as Twitter DM
- Missing user_identity when sending the reset password notification
- Legacy protocol values are considered as valid

## [0.13.0] 2018-11-30

### Added

- API to manage cryptographic public keys related to a contact
- API to list known remote identity providers
- Create remote identity for gmail and twitter using Oauth mechanisms
- A new worker to fetch twitter direct messages
- Support touch scroll on navigation tabs
- Manage public keys of a contact
- App loader splash screen

### Changed

- Brand new UI
- Message Timeline replaced by Discussion Timeline
- IM address for a contact is more permisive

### Removed

- Sidescreen on small screen
- In discussion messages grouped by date

### Fixed

- Translation of new device screen in English

## [0.12.3] 2018-10-26

### Fixed

- Manage better how to declare an user index on signup
- Index contact and message with correct user_id

### Changed

- Build go images with a vendor sync and with CA certificates for TLS connection

## [0.12.2] 2018-10-15

### Fixed

- /suggest apiv2 route use user.shard_id index not user.user_id
- message python object use user not user_id

## [0.12.1] 2018-10-04

### Fixed

- Share an index for many users, scalibility of elasticsearch does not work
  using old scheme

### Added

- Add an email or a social identity to a contact trigger PGP key discovery
  process
- A connection is possible per device

### Changed

- prevent invalidation of whole discussion during scroll
- LocalIdentities and RemoteIdentities have been merged into a new UserIdentity
  object
- group discussion by list or all participants
- API output more informations on discussions

### Fixed

- message sort on "Load More" in discussion view
- revert mis-deleted signup and recovery mail links

## [0.11.2] 2018-07-16

### Fixed

- load more doesn't load correctly when filter has been changed
- prevent signin until JS is fully loaded, previously a json shows up with
  informations about a fake device.
- unlock correctly syncing state after a fetch failure
- safer parsing of email with ',' or '\r' character

### Changed

- remove unused safe/public/unsafe login buttons

## [0.11.1] 2018-07-12

### Added

- explain how to authorize retrieve of an imap gmail account

### Fixed

- do not try to parse a null date_sort
- ensure to not retrieve credentials when patching a remote identity
- RawMessage.get raise correctly
- request body must be utf8 encoded correctly, do not use it for the moment

## [0.11.0] 2018-07-04

### Added

- client sign HTTP queries
- API v1 and v2 check signed ecdsa http queries, but only log result
- delete an user account
- API for remote identities management
- client can create an IMAP remote identities
- poll remote identities to fetch an IMAP source
- can use hashicorp vault to store sensible informations
- fetch list of messages surrounding a given message
- a go CLI to fix empty message participants

### Changed

- optimization, prevent timeline to fetch multiple times the API
- Internal email delivery is more reliable, with better error handling,
  reporting and logging.
- scroll better on messages list

### Fixed

- scrolls to specific message, and restore scroll positions when navigating
  between tabs.
- change parent of a draft has no effects
- sort messages of a discussion
- discussion might not be up to date after creating a draft
- sending two consecutives messages was failing when the second message is saved
  before clicking on the send button.
- contact lookup can reference a deleted contact, don't fail

## [0.10.1] 2018-05-18

### Fixed

- a discussion_id should not be removed when patching a draft
- bad device type mapping for smartphone devices, authentication wasn't possible
- read message are flagged correctly read
- search bar is more visible

## [0.10.0] 2018-05-14

### Added

- Confirmation is asked before deleting a message, a discussion or a contact
- Messages have new computed property : `date_sort`. Messages' list is sorted
  on.
- Basic support of new message's notifications
- Poller and worker for IMAP remote identities fetch in backend

### Changed

- in mobile view, draft form can toggle with an excerpt to not use half of the
  screen
- Power to the not found unicorn

### Fixed

- Make favicon accessible without authentication

## [0.9.2] 2018-04-12

### Fixed

- prevent button background color to change on hover when disabled
- The draft delete button was always disabled even when draft was saved
- The max file size was not rendered (attachments/contacts..)

## [0.9.1] 2018-04-05

### Fixed

- check if contact.title is null or undefined when displaying ContactBook

## [0.9.0] 2018-03-29

### Added

- Manage draft's attachements
- Download message's attachements
- Set context (safe, public, not safe) on signin (it has no effects yet)
- Multiple messages delete on Timeline
- Multiple messages' tags management on Timeline
- Device management first part: declare new device with an ecdsa key
- Backend notification base principle with a related API

### Changed

- Refactor vcard parsing logic to get more informations
- Contacts API are now v2
- Authenticate with a context and a device (known or a new one to declare)
- Better email body sanitization
- When updating a contact, compute it's new PI asynchronously

### Fixed

- Explain that the NSA joke is a joke using a `:)`

## [0.8.1] 2018-01-25

### Fixed

- messages filtered by status draft/sent/received wasn't up-to-date
- checkbox wasn't correctly checked in settings
- fix BSOD (Black Screen Of Death) when an author is not in user's contact book

## [0.8.0] 2018-01-19

### Added

- Tags management: user's tags, tags on messages and contacts
- add a `internal` tag to messages sent from the same instance than receiver

### Fixed

- trim spaces in username on signin page
- unable to load more messages on Timeline

## [0.7.0] 2017-12-22

### Added

- Timeline filter (all, received, sent, drafts)
- Add a is_received flag on message structure
- Add german translations
- Add take a tour for current features

### Changed

- Do not save the draft until body or participants is filled
- Move activity spinner to the top right of contact page
- Prevent double click on contact save

### Fixed

- Signout on mobile doesn't disconnect
- suggest participants fails if a contact has no emails
- Max body size of a request (import contact)
- Sort message by date sent for user's messages
- Settings can be saved when display delay is changed
- A draft still appears after been deleted
- Show correctly the message in reply on the current draft
- Notify when saving contact failed
- Refresh contacts after a deletion
- Get browsers' autofills on SigninForm

## [0.6.0] 2017-11-24

### Added

- Reset password
- do not force phone nnumber normalization, accept everything and try to
  normalize
- permit to set contact title on user input, do not compute it strictly

### Changed

- User's contact cannot be deleted anymore
- The name of the Timeline tab is now "Messages" instead of "Discussions"

### Fixed

- Do not close the dropdown when receiving new suggestions
- Disable send message when already sent and add visual feedback (spinner)
- Disable import contact button on uploading and add a spinner
- Save updated password strength after password modification
- Set max file size for contact import
- Efficient search highlights
- Access to /user/security route
- Contact's name consistency
- On editing/creating contact, disable submit button if form is untouched

## [0.5.5] 2017-11-13

### Added

- Reset password API
- In a draft, press comma or semicolon key to add a recipient
- Basic search in messages and contacts
- Delete a contact
- Change password

### Fixed

- In a draft to edit last recipient, pressing backspace does not remove last
  letter
- In a draft, click outside of recipient list add a recipient
- Unmarshal nested empty structures in go objects.
- Save updated password strength after password modification

## [0.5.4] 2017-11-03

### Fixed

- unmarshal nested empty structures in go objects
- ancestors_id always an array, even empty
- save a draft notify correctly

## [0.5.3] 2017-11-02

### Added

- Delete a message from Timeline
- Delete a draft
- Notify the user the draft is saved after a manual save

### Fixed

- Disable buttons send and save when draft is untouched
- ancestors_id empty array and not null

## [0.5.2] 2017-10-31

### Fixed

- piwik site id environment variable ok with client build #590
- lower case local identity lookup #589
- empty string instead of none for family name #587
- plain text body unescaped only #586
- enforce uuid validation in apiv2 #584

## [0.5.1] 2017-10-29

### Fixed

- fix sort in discussions
- support https in api query configuration
- Render correctly the frontend Server Side (%MARKUP% will not show up anymore)
- fix empty UUID on patch #574
- lmtp crash with invalid nats message #575
- attach correctly to same discussion first outbound message and its reply #566
- handle better invalid message unmarshalling #579

## [0.5.0] 2017-10-25

### Added

- create new contact
- the excerpt of the message in reply into draft form
- frontend custom settings for the instance and the running environment
- API to allow users to change their password, with email notification
- Compute first contact privacy features
- Permit to restrict registration to a whitelist of user recovery emails

## [0.4.0]

### Added

- Connect settings and apply
- The brand new Timeline
- Load more in the discussions
- API for importance level messages filtering
- API for full-text searches on messages & contacts
- Compute importance level v0 for inbound messages

### Changed

- Improve `PATCH` API
- Backend produces `excerpt` for messages.
- Backend produces plain or rich body using setting value
- Frontend: refactoring Dropdown

### Fixed

- Render tag list in contact book

## [0.3.0] 2017-08-31

### Added

- A python package caliopen_pi to group all logic related to privacy index
  compute
- Add route `GET /v2/contacts/{contact_id}/identities` to search & retrieve
  identities from a contact.
- New scene components related to Settings layout
- New Importance Level range slider in tabs & alt navigation
- In compose, add subject input field when recipient uses an email
- Install postcss-loader and Autoprefixer (run by webpack)
- Add user settings storage and API for management (GET and PATCH /settings)
- Frontend can post draftID
- Messages have 2 bodies : plain + HTML.
- Only one body is returned to frontend for Message.
- HTML body is sanitized before output to frontend.
- MailMessages's subject decoded to always output an UTF-8 string.
- Index operations return after index has been fully updated
- API /v1/discussions returns messages ordered by last_messsage date_insert
  field.

### Changed

- Rename <Account...> layout and related scenes to <User...>
- Display notification if contact update failed
- support TAB for adding a participant to a discussion
- use participant suggestions API for a new message
- Handle 4xx errors when updating contact fails
- Compose in multiple tabs messages, not only one.
- Cross-browser `<select>` element styles.
- Refactor caliopen_main package for cleaner namespaces.
- Move tags API to V2. CRUD operations are now on routes /v2/tags
- Discussions creation from ingress messages are build from messages' external
  references.
- ingress & egress JSON payload are double validated by our API instead of only
  relying on swagger.

### Fixed

- Bad wording for message update failures
- Blink when composing a new message
- Inconsistent date format string across stack
- Bugs on patch operations (contact & messages)
- Missing 'title' property on the user's Contact card
- Elasticsearch inconsistent mapping

## [0.2.1] - 2017-07-04

### Added

- GET /identities/remotes/<identifier> route to fix issue #383
- add a docker compose for staging platform

## [0.2.0] - 2017-07-02

### Added

- Participants suggestion API
- Basic user remote identities API
- API for attachment management during draft composition
- Backend for outbound email message build with attachements
- Basic privacy features extraction and pi computation when processing inbound
  email
- PI attribute added to user, public_key, contact, message entities
- Contact vcard import API and client implementation
- Contact book plugged with API
- Tabbed navigation
- Messages of a discussion
- Add or reply save draft message
- Send a draft message
- Basic import of a contact book
- Add piwik, the analytics plateform for the alpha testing purpose

### Changed

- Remove any cassandra counters and secondary index usage
- Replace cassandra with scylladb in development stack
- Upgrade elasticsearch from 2.4 version to 5.x ones
- Network optimizations when loading the client
- Infinite scroll on the lists
- Display real contact book (previous was fake)

## [0.1.0] - 2017-05-07

### Added

- Initial release
- Basic inbound email processing using NATS as message queue broker
- Contact API
- Message API
- Timeline build on basic discussion structure
- development CLI with basic commands to manage storage and load fixtures
- docker compose development stack
- Account creation
- Basic devices management
- Basic tags management


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

First of all, thank you for contributing, you are awesome!

- Report a bug or post a feature request: https://feedback.caliopen.org/
- [Installation process](doc/install) for development purpose
- You don't where to start and you want something simple to do?
  [Take a look to the good first issues](https://github.com/CaliOpen/Caliopen/labels/good%20first%20issue)
- You are more involved on Caliopen developments, please read the
  [Welcome Guide](./doc/welcome.md)

## Code of conduct

As in CaliOpen: _**Be Good**_. And be nice.

_(This code of conduct may evolve)_.

## Core Team

- [@LaurentChemla](https://github.com/LaurentChemla)
- [@gdchamal](https://github.com/gdchamal)
- [@iamdey](https://github.com/iamdey)

## Contributors

Of course we can't show all of you from https://feedback.caliopen.org/. Thank
you all!

- [@mardiros](https://github.com/mardiros)
- [@cr0cK](https://github.com/cr0cK)
- [@steventlucek](https://github.com/steventlucek)
- [@themouette](https://github.com/themouette)
- [@ziir](https://github.com/ziir)
- [@ncoden](https://github.com/ncoden)
- [@yanndinendal](https://github.com/yanndinendal)
- [@pascalduez](https://github.com/pascalduez)
- [@dgramop](https://github.com/dgramop)
- alban
- vinci
- [@Zeriuno](https://github.com/Zeriuno)
- The NSA (to make it happen)
- [@ptran32](https://github.com/ptran32)
- [@Mindiell](https://github.com/Mindiell)
- [@goofy-bz](https://github.com/goofy-bz)
- [@josepot](https://github.com/josepot)
- [@lisonferez](https://github.com/lisonferez)
- [@didimoo](https://github.com/didimoo)
- [@octplane](https://github.com/octplane)
- [@myleneb](https://github.com/myleneb)
- [@judbd](https://github.com/orgs/CaliOpen/people/judbd)
- [@Lauth0](https://github.com/Lauth0)
- [@sapiens-sapide](https://github.com/sapiens-sapide)
- [@MonsieurLanza](https://github.com/MonsieurLanza)


================================================
FILE: LICENSE
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.


================================================
FILE: README.md
================================================
# Caliopen Messaging Platform

[![Build Status](https://travis-ci.org/CaliOpen/Caliopen.svg)](https://travis-ci.org/CaliOpen/Caliopen)

> The best way to discuss with your contacts, while preserving your privacy.

![Actual alpha version](doc/assets/caliopen_ui.jpg)

This repository hosts all the source code, the scripts and the tools for the
[CaliOpen](https://caliopen.org) project.


## Features requests, Issues, Pull Requests or share the love

Tell us whatever you want:
* our discourse: [feedback](https://feedback.caliopen.org/)
* Twitter [@caliopen_org](https://twitter.com/caliopen_org)
* IRC on [Freenode #caliopen](irc://chat.freenode.net:6697/caliopen).

**Some usefull links for developers:**

* Global documentation on [readthedocs](http://caliopen.readthedocs.io/en/latest/)
* Some contributing resources: [CONTRIBUTING.md](CONTRIBUTING.md)

## Installation

Unfortunately Caliopen is not yet ready for production.


================================================
FILE: devtools/ES_queries/Recipient_suggest.json
================================================
{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "participants",
            "query": {
              "bool": {
                "should": [
                  {
                    "wildcard": {
                      "participants.label": "*laurent*"
                    }
                  },
                  {
                    "wildcard": {
                      "participants.address": "*laurent*"
                    }
                  }
                ]
              }
            },
            "inner_hits": {}
          }
        },
        {
          "bool": {
            "should": [
              {
                "wildcard": {
                  "given_name": {
                    "value": "*laurent*",
                    "boost": 2
                  }
                }
              },
              {
                "wildcard": {
                  "family_name": {
                    "value": "*laurent*",
                    "boost": 2
                  }
                }
              }
            ]
          }
        },
        {
          "nested": {
            "path": "emails",
            "query": {
              "bool": {
                "should": [
                  {
                    "wildcard": {
                      "emails.label": {
                        "value": "*laurent*",
                        "boost": 2
                      }
                    }
                  },
                  {
                    "wildcard": {
                      "emails.address": {
                        "value": "*laurent*",
                        "boost": 2
                      }
                    }
                  }
                ]
              }
            },
            "inner_hits": {}
          }
        }
      ]
    }
  },
  "aggs": {
    "last_messages": {
      "max": {
        "field": "date"
      }
    }
  },
  "_source": [
    "date",
    "type",
    "given_name",
    "family_name"
  ]
}

================================================
FILE: devtools/Vagrantfile
================================================
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  config.vm.box = "debian/contrib-jessie64"
  # config.vm.box_check_update = false

  # ReST API port
  config.vm.network "forwarded_port", guest: 6543, host: 6543
  # LMTP port
  config.vm.network "forwarded_port", guest: 4025, host: 4025
  # Web client port
  config.vm.network "forwarded_port", guest: 4000, host: 4000



  # config.vm.network "private_network", ip: "192.168.33.10"
  # config.vm.network "public_network"
  config.vm.synced_folder "../", "/opt/caliopen/code"


  config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
     vb.memory = "2048"
  end
  config.vm.provision :shell, path: "./bootstrap-debian.sh"
end


================================================
FILE: devtools/api-mock/README.md
================================================
# API mock

The purpose of this package is to mock the whole API using [bouchon][bouchon], it uses redux to
collect and render data in an oriented ReSTful server.

## Requirements

* [Node.js][node] >= 6
* [yarn][yarn] >= 0.21

## Usage

Launch `bin/start`, it will install and start the mock server on port `31415`.

## Dev

The entry file is `all.fixture.js`, it loads all routes (and config) in the Javascript ES6 way.

Each "route" folders contain configs and [redux][redux] actions and reducers in the `index.js` file
and the initial fixtures in `data.json`.

There a middleware to tweak the response (e.g for route collection).

## TODO

It could great to:

* validates the response using a swagger parser and throw when the response is no more consistent
with the real API
* generate fake datas (faker.js) for not configured routes (using the swagger parser)

[bouchon]: https://github.com/cr0cK/bouchon
[node]: http://nodejs.org/
[yarn]: https://yarnpkg.com
[redux]: http://redux.js.org/


================================================
FILE: devtools/api-mock/all.fixture.js
================================================
require('babel-core/register');
require('babel-polyfill');

module.exports = {
  default: [
    require('./authentications').default,
    require('./contacts').default,
    require('./devices').default,
    require('./discussions').default,
    require('./local_identities').default,
    require('./me').default,
    require('./messages').default,
    require('./notifications').default,
    require('./oauth-mock').default,
    require('./participants').default,
    require('./providers').default,
    require('./remote_identities').default,
    require('./search').default,
    require('./settings').default,
    require('./tags').default,
  ],
};


================================================
FILE: devtools/api-mock/authentications/data.json
================================================
{
	"tokens": {
		"access_token": "de85ce575fe7f6262e0cd11582ff33ee848f1027",
		"expires_at": "2017-03-07T13:37:39.280870",
		"expires_in": 99999999999,
		"refresh_token": "f8576a2b8e1e6967b5a58a195b32e860fa8076ca34768d6b6e7a957ae95fff6214167af26f67455e"
	},
	"user_id": "d46d717a-57f5-4b11-b086-11caeac05261",
	"username": "john",
	"device": {
		"device_id": "",
		"status": ""
	}
}


================================================
FILE: devtools/api-mock/authentications/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { actions as devicesAction, selectors as devicesSelector } from '../devices';
const actions = {
  post: createAction('Authenticate'),
};

const selectors = {
  all: (params) => createSelector(
    [
      ({ authentications }) => authentications,
      devicesSelector.byId({ device_id: params.device.device_id }),
    ],
    (authentications, device) => ({
      ...authentications,
      device,
    })
  ),
};

const reducer = {};

const routes = {
  'POST /': {
    action: [devicesAction.createOnSignin, actions.post],
    selector: selectors.all,
    status: 200,
  },
};

export default {
  name: 'authentications',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v1/authentications',
  routes: routes,
};


================================================
FILE: devtools/api-mock/bin/start
================================================
#!/bin/bash

# Generate swagger specifications from JSON schema definitions

set -e
PROJECT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
SCRIPT_PATH=${PROJECT_DIRECTORY}/node_modules/.bin/bouchon
CMD="yarn start"


if [[ ! -f "${SCRIPT_PATH}" ]]; then
	echo "You should have nodejs > 6 and yarn"

	(cd $PROJECT_DIRECTORY && yarn install)
fi


(cd $PROJECT_DIRECTORY && ${CMD})

set +e


================================================
FILE: devtools/api-mock/collection-middleware/index.js
================================================
const createCollectionMiddleware = entityName => data => (req, res, next) => {
  res.data = {
    total: data.length,
    [entityName]: data,
  };

  next();
};

export default createCollectionMiddleware;


================================================
FILE: devtools/api-mock/contacts/data.json
================================================
[{
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "c-john-01",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "u-john-01",
  "title": "John",
  "additional_name": "",
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "John Dœuf",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 87, "context": 45, "comportment": 25 },
  "tags": ["me"],
  "infos": {
    "birthday": "2016-05-09T15:01:42.11600"
  },
  "emails": [{
    "email_id": "me-email",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "john@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "home"
  }],
  "family_name": "Dœuf",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "92d3727a-eefc-4537-b879-85f1c9d197bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "u-john-01",
  "title": "Bender",
  "additional_name": "",
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Bender Bending",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 87, "context": 45, "comportment": 25 },
  "tags": ["robot", "planet-express"],
  "infos": {
    "birthday": "2016-05-09T15:01:42.11600"
  },
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000001",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "bender@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "Rodriguez",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "0ba2e346-e4f8-4c45-9adc-eeb1d42fuie0",
  "date_insert": "2016-05-09T15:01:43.381000",
  "identities": [],
  "user_id": "344489c3-fc63-4e41-b490-5f4dd317aa51",
  "title": "Zoidberg",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Zoidberg",
  "name_prefix": "Dr",
  "deleted": 0,
  "pi": { "technic": 50, "context": 45, "comportment": 25 },
  "tags": ["robot", "INPORTANT"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000002",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "zoidberg@caliopen.local",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }, {
    "email_id": "93f03145-4398-4bd4-9bd5-00000003",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "zoidberg@planet-express.tld",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "work"
  }],
  "family_name": "Zoidberg",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "19c3ui42-e3ba-46e7-984f-4c3e8de11c05",
  "date_insert": "2016-05-09T15:01:40.034000",
  "identities": [],
  "user_id": "344489c3-tref-4e41-b490-5f4dd317aa52",
  "title": "Leela",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Leela",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 87, "context": 20, "comportment": 25 },
  "tags": ["planet-express"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000100",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "leela@john.doe",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Turanga",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "92d3907a-eeui-4537-b229-85f1c9d197bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "344489c3-fc63-4e41-b490-5f4dd1234553",
  "title": "Fry",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Philip J.",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 87, "context": 45, "comportment": 35 },
  "tags": ["humans", "planet-express"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00002001",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "fry@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "Fry",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "0ba2e346-e4f8-4c45-999c-eeb1d42f07e0",
  "date_insert": "2016-05-09T15:01:43.381000",
  "identities": [],
  "user_id": "344489c3-gtpu-4e41-b490-5f4dd317aa54",
  "title": "Amy",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Amy",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 45, "context": 34, "comportment": 25 },
  "tags": ["humans", "planet-express"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000022",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "amy@caliopen.local",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Wong",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "19c3ce42-e3ba-46e7-902f-4cui8de11c05",
  "date_insert": "2016-05-09T15:01:40.034000",
  "identities": [],
  "user_id": "344489c3-hyzc-4e41-b490-5f4dd317aa55",
  "title": "Farnsworth",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Hubert J.",
  "name_prefix": "Prof.",
  "deleted": 0,
  "pi": { "technic": 46, "context": 45, "comportment": 87 },
  "tags": ["humans", "planet-express"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000120",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "professor@planet.express",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Farnsworth",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "9ui3907a-eefc-4537-b229-85f1c9d197bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "344489c3-bjsq-4e41-b490-5f4dd317aa53",
  "title": "Lrrr",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Lrrr",
  "name_prefix": "Emperor",
  "deleted": 0,
  "pi": { "technic": 87, "context": 20, "comportment": 50 },
  "tags": ["aliens"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-02000001",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "lrrr@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "98o3907a-eefc-6724-bv28-85f1c9d197bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "344489c3-olds-4e41-b490-5f4dd317aa53",
  "title": "Stephen Hawking",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Stephen",
  "name_prefix": "Dr",
  "deleted": 0,
  "pi": { "technic": 10, "context": 15, "comportment": 25 },
  "tags": ["humans"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-20020001",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "stephen@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "Hawking",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "0327707a-eefc-6724-bv28-85f1c9d197bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "355489c3-olds-4e41-b490-5f4dd317aa53",
  "title": "Kif",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Kif",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 4, "context": 24, "comportment": 25 },
  "tags": ["aliens", "planet-express", "amphibians"],
  "infos": {},
  "emails": [{
    "email_id": "0327707a-4398-4bd4-9bd5-20020001",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "kroker@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "Kroker",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "5488707a-eefc-6724-bv28-85f1c9d197bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "356489c3-olds-4e41-b490-5f4dd317aa53",
  "title": "Zapp Brannigan",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Zapp",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 41, "context": 15, "comportment": 25 },
  "tags": ["humans"],
  "infos": {},
  "emails": [{
    "email_id": "5488707a-4398-4bd4-9bd5-20020001",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "zapp@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "Brannigan",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "19c3ce42-e3ba-46e7-902f-4cui8d",
  "date_insert": "2016-05-09T15:01:40.034000",
  "identities": [],
  "user_id": "340089c3-hyzc-4e41-b490-5f4dd317a",
  "title": "Elzar",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Elzar",
  "name_prefix": "Chef",
  "deleted": 0,
  "pi": { "technic": 48, "context": 45, "comportment": 25 },
  "tags": ["aliens"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000120",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "francine@doop",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "a3ce42-e3ba-46e7-902f-4cfdsfsui8d",
  "date_insert": "d016-05-09T15:01:40.034000",
  "identities": [],
  "user_id": "40489c3-hyzc-4e41-b490-5f4dd317a",
  "title": "Scruffy",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Scruffy",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 87, "context": 45, "comportment": 35 },
  "tags": ["humans", "planet-express"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000120",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "algore@caliopen.local",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Scruffington",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "a3ce42-e3ba-46e7-dfsd902f-4cui8d",
  "date_insert": "d016-05-09T15:01:40.034000",
  "identities": [],
  "user_id": "04489c3-hyzc-4e41-b490-5f4dd317a",
  "title": "Hermès",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Hermès",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 87, "context": 70, "comportment": 95 },
  "tags": ["humans", "planet-express"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00000120",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "Conrad@caliopen.local",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Conrad",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "92d3727a-eefc-4537-b879-85f1c7bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "u-john-01",
  "title": "Flexo",
  "additional_name": "",
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Flexo",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 48, "context": 56, "comportment": 32 },
  "tags": ["robot"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00900001",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "flexo@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "0ba2e346-e4f8-4c45-9adc-eeb1die0",
  "date_insert": "2016-05-09T15:01:43.381000",
  "identities": [],
  "user_id": "344489c3-fc63-4e41-b490-5f4dd317aa51",
  "title": "Calculon",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Antonio",
  "name_prefix": "",
  "deleted": 0,
  "pi": { "technic": 10, "context": 15, "comportment": 12 },
  "tags": ["robot"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-90000002",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "calc@caliopen.local",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Calculon",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "19c3ui42-e3ba-46e7-984f-4c3e8c05",
  "date_insert": "2016-05-09T15:01:40.034000",
  "identities": [],
  "user_id": "344489c3-tref-4e41-b490-5f4dd317aa52",
  "title": "Mom",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 56, "context": 35, "comportment": 7 },
  "tags": ["humans"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00900100",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "mom@john.doe",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Mom",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "92d3907a-eeui-4537-b229-85f197bb",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "344489c3-fc63-4e41-b490-5f4dd1234553",
  "title": "Morbo the Annihilator",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Morbo",
  "name_prefix": null,
  "deleted": 0,
  "pi": { "technic": 41, "context": 45, "comportment": 7 },
  "tags": ["aliens"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00002901",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "morbo@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "0ba2e346-e4f8-4c45-999c-eeb107e0",
  "date_insert": "2016-05-09T15:01:43.381000",
  "identities": [],
  "user_id": "344489c3-gtpu-4e41-b490-5f4dd317aa54",
  "title": "Panucci",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "",
  "name_prefix": "Mr.",
  "deleted": 0,
  "pi": { "technic": 20, "context": 45, "comportment": 75 },
  "tags": ["humans"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-00900022",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "Panucci@caliopen.local",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "Panucci",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "19c3ce42-e3ba-46e7-902f-4cuie11c05",
  "date_insert": "2016-05-09T15:01:40.034000",
  "identities": [],
  "user_id": "344489c3-hyzc-4e41-b490-5f4dd317aa55",
  "title": "Nibbler",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Nibbler",
  "name_prefix": "Lord",
  "deleted": 0,
  "pi": { "technic": 65, "context": 45, "comportment": 25 },
  "tags": ["aliens", "planet-express"],
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-0009120",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "nib@planet.express",
    "date_insert": "2016-05-09T15:01:43.116000",
    "type": "other"
  }],
  "family_name": "",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}, {
  "addresses": [],
  "privacy_features": {},
  "phones": [],
  "contact_id": "9ui3907a-eefc-4537-b229-f1c9d19b",
  "date_insert": "2016-05-09T15:01:42.381000",
  "identities": [],
  "user_id": "344489c3-bjsq-4e41-b490-5f4dd317aa53",
  "title": "Hypnotoad",
  "additional_name": null,
  "date_update": null,
  "organizations": [],
  "ims": [],
  "given_name": "Hypnotoad",
  "name_prefix": "",
  "tags": ["amphibians", "aliens"],
  "deleted": 0,
  "pi": { "technic": 87, "context": 75, "comportment": 25 },
  "infos": {},
  "emails": [{
    "email_id": "93f03145-4398-4bd4-9bd5-02000901",
    "is_primary": 0,
    "date_update": null,
    "label": null,
    "address": "Hypnotoad@caliopen.local",
    "date_insert": "2016-05-09T15:01:42.116000",
    "type": "other"
  }],
  "family_name": "",
  "name_suffix": null,
  "avatar": "avatar.png",
  "public_keys": []
}]


================================================
FILE: devtools/api-mock/contacts/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

const actions = {
  get: createAction('Get contacts'),
  patch: createAction('Patch contact'),
  post: createAction('Post contact'),
  patchTags: createAction('Patch contact\'s tags'),
};

const selectors = {
  all: () => state => state.contacts,
  byId: ({ contact_id }) => createSelector(
    selectors.all(),
    contacts => {
      const contact = contacts.find(contact => contact.contact_id === contact_id);
      if (contact) {
        return contact;
      }

      throw new Error('contact not found');
    }
  ),
  last: () => state => [...state.contacts].pop(),
  lastLocation: () => createSelector(
    selectors.last(),
    contact => ({ location: `/api/v2/contacts/${contact.contact_id}` })
  ),
};

const reducer = {
  [actions.post]: (state, { body }) => ([
    ...state,
    {
      contact_id: uuidv1(),
      ...body,
    },
  ]),
  [actions.patch]: (state, { params, body }) => {
    const nextState = [...state];
    const original = state.find(contact => contact.contact_id === params.contact_id);
    if (!original) {
      throw `contact w/ id ${params.contact_id} not found`;
    }
    const index = nextState.indexOf(original);
    const { current_state, ...props } = body;
    nextState[index] = {
      ...original,
      ...props,
    };

    return nextState;
  },
  [actions.patchTags]: (state, { params, body }) => {
    const original = state.find(contact => contact.contact_id === params.contact_id);
    if (!original) {
      throw `contact w/ id ${params.contact_id} not found`;
    }

    const index = state.indexOf(original);
    const nextState = [...state];
    const { tags } = body;

    nextState[index] = {
      ...original,
      tags,
    };

    return nextState;
  },
};

const routes = {
  'GET /v2/contacts/': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
    middlewares: [createCollectionMiddleware('contacts')],
  },
  'GET /v2/contacts/:contact_id': {
    action: actions.get,
    selector: selectors.byId,
    status: 200,
  },
  'PATCH /v2/contacts/:contact_id': {
    action: actions.patch,
    status: 204,
  },
  'POST /v2/contacts/': {
    action: actions.post,
    selector: selectors.lastLocation,
    status: 200,
  },
  'PATCH /v2/contacts/:contact_id/tags': {
    action: actions.patchTags,
    status: 204,
  },
};

export default {
  name: 'contacts',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api',
  routes: routes,
};


================================================
FILE: devtools/api-mock/devices/data.json
================================================
[
  {
    "device_id": "00001",
    "ecdsa_key": {
      "curve": "P-256",
      "hash": "SHA256",
      "x": "fd73920f7e2ad3ce524b5b08cab21357dd6a4d7d5d3c267e42a834d8ac1af244",
      "y": "1bf08f940c720b5a021863f03029cbf62ea7a4837460da957be9f4704eff76bd"
    },
    "status": "unverified",
    "name": "device to revoke",
    "type": "smartphone"
  }
]


================================================
FILE: devtools/api-mock/devices/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

export const actions = {
  get: createAction('Get devices'),
  createOnSignin: createAction('Create device'),
  delete: createAction('Delete a device'),
  patch: createAction('Patch a device'),
  reqVerif: createAction('Req Verif of a device'),
  verify: createAction('Verify'),
};

export const selectors = {
  all: () => state => state.devices,
  last: () => state => [...state.devices].pop(),
  byId: ({ device_id }) => createSelector(
    selectors.all(),
    devices => devices.find(device => device.device_id === device_id)
  ),
  location: () => createSelector(
    selectors.last(),
    device => ({ location: `/api/v2/devices/${device.device_id}` })
  ),
};

const devicesToIgnore = new Set(['00001']);

const reducer = {
  [actions.createOnSignin]: (state, { body, req }) => {
    const { device_id } = body.device;
    const hasDevice = state.some(device => device.device_id === device_id);
    const hasVerifiedDevice = state
      .filter(device => !devicesToIgnore.has(device.device_id))
      .some(device => device.status === 'verified');

    if (hasDevice) {
      return state;
    }

    const device = {
      ...body.device,
      status: !hasVerifiedDevice ? 'verified' : 'unverified',
      name: !hasVerifiedDevice ? 'default' : `desktop ${state.length}`,
    };

    return [
      ...state,
      device,
    ];
  },
  [actions.get]: state => state,
  [actions.delete]: (state, { params }) => {
    const copy = state.slice(0);
    return [...state].filter(device => device.device_id !== params.device_id);
  },
  [actions.patch]: (state, { params, body }) => {
    const nextState = [...state];
    const original = state.find(device => device.device_id === params.device_id);
    if (!original) {
      throw `device w/ id ${params.device_id} not found`;
    }
    const index = nextState.indexOf(original);
    const { current_state, ...props } = body;
    nextState[index] = {
      ...original,
      ...props,
    };

    return nextState;
  },
  [actions.reqVerif]: (state, { params, body }) => {
    const original = state.find(device => device.device_id === params.device_id);
    if (!original) {
      throw `device w/ id ${params.device_id} not found`;
    }
    const { actions } = body;

    if (actions[0] !== 'device-validation') {
      throw new Error('Unknown action');
    }

    return state;
  },
};

const routes = {
  'GET /devices/': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
    middlewares: [createCollectionMiddleware('devices')],
  },
  'GET /devices/:device_id': {
    action: actions.get,
    selector: selectors.byId,
    status: 200,
  },
  'DELETE /devices/:device_id': {
    action: actions.delete,
    status: 204,
  },
  'PATCH /devices/:device_id': {
    action: actions.patch,
    status: 204,
  },
  'POST /devices/:device_id/actions': {
    action: actions.reqVerif,
    status: 204,
  },
  'GET /validate-device/:token': {
    action: actions.verify,
    status: 204,
    middlewares: [data => (req, res, next) => {
      if (req.params.token === 'fail') {
        res.status(500);

        return;
      }
      if (req.params.token !== 'aaaa-bbbb') {
        res.status(404);

        return;
      }
    }],
  },
};

export default {
  name: 'devices',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2',
  routes: routes,
};


================================================
FILE: devtools/api-mock/discussions/data.json
================================================
[
  {
    "tags": [
      {
        "tag_id": "foo-bar-1",
        "name": "robot",
        "type": "user"
      },
      {
        "tag_id": "foo-bar-2",
        "name": "work",
        "type": "system"
      }
    ],
    "last_message_id": "11111111-267d-4d9c-97ee-d0fc59c64202",
    "last_message_subject": "",
    "excerpt": "Fry! Stay back! He's too powerful! Can I use the gun? I barely knew Philip, but as a ...",
    "privacy_index": 1,
    "participants": [
      {
        "label": "test",
        "type": "Cc",
        "contact_ids": ["1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
        "address": "test@caliopen.local",
        "protocol": "email"
      },
      {
        "type": "To",
        "label": "Jaune",
        "contact_ids": ["c-john-01"],
        "address": "john@caliopen.local",
        "protocol": "email"
      },
      {
        "label": "zoidberg",
        "type": "From",
        "address": "zoidberg@planet-express.tld",
        "protocol": "email"
      }
    ],
    "date_insert": "2017-03-21T10:55:00.153000+00:00",
    "date_update": "2017-03-21T10:55:00.153000+00:00",
    "discussion_id": "cd53e13a-267d-4d9c-97ee-d0fc59c64200",
    "total_count": 1,
    "attachment_count": 0,
    "importance_level": 0,
    "unread_count": 1
  },
  {
    "tags": [
      {
        "tag_id": "foo-bar-3",
        "name": "best quotes",
        "type": "user"
      },
      {
        "tag_id": "foo-bar-4",
        "name": "lolilol",
        "type": "user"
      }
    ],
    "excerpt": "Shut up and take my money! Leela, are you alright? You got wanged on the he=\r\nad. Bender, you risked your life To save me! Spare me your space age techno=\r\nbabble, Attila the Hun! Now that the, uh, ga",
    "privacy_index": 25,
    "participants": [
      {
        "type": "From",
        "contact_ids": ["c-john-01", "1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
        "address": "john@caliopen.local",
        "protocol": "email",
        "label": "Jaune"
      },
      {
        "type": "To",
        "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42f07e0"],
        "address": "fry@planet-express.tld",
        "protocol": "email",
        "label": "fry"
      }
    ],
    "date_insert": "2017-03-21T10:55:00.153000+00:00",
    "date_update": "2017-03-21T10:55:00.153000+00:00",
    "discussion_id": "46d30c27-6cd8-407b-8536-fda4196c20ca",
    "last_message_id": "2222222-267d-4d9c-97ee-d0fc59c64201",
    "last_message_subject": "Shut up and take my money",
    "total_count": 2,
    "attachment_count": 2,
    "importance_level": 0,
    "unread_count": 2
  },
  {
    "tags": [],
    "excerpt": "delete a message",
    "privacy_index": 25,
    "participants": [
      {
        "type": "From",
        "contact_ids": ["1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
        "address": "john@caliopen.local",
        "label": "Jaune",
        "protocol": "email"
      },
      {
        "type": "To",
        "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42f07e0"],
        "address": "removeme@caliopen.local",
        "protocol": "email",
        "label": "Remove Me"
      }
    ],
    "date_insert": "2017-03-21T10:55:00.153000+00:00",
    "date_update": "2017-03-21T10:55:00.153000+00:00",
    "discussion_id": "3330c27-6cd8-407b-8536-fda4196c20ca",
    "last_message_subject": "remove message one by one",
    "last_message_id": "3333-267d-4d9c-97ee-d0fc59c64201",
    "total_count": 2,
    "attachment_count": 2,
    "importance_level": 0,
    "unread_count": 2
  },
  {
    "tags": [],
    "excerpt": "delete all messages",
    "privacy_index": 25,
    "participants": [
      {
        "type": "From",
        "contact_ids": ["1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
        "address": "john@caliopen.local",
        "protocol": "email",
        "label": "Jaune"
      },
      {
        "type": "To",
        "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42f07e0"],
        "address": "removeall@caliopen.local",
        "protocol": "email",
        "label": "Remove'em all"
      }
    ],
    "date_insert": "2017-03-21T10:55:00.153000+00:00",
    "date_update": "2017-03-21T10:55:00.153000+00:00",
    "discussion_id": "44440c27-6cd8-407b-8536-fda4196c20ca",
    "last_message_subject": "remove messages",
    "last_message_id": "5555-267d-4d9c-97ee-d0fc59c64201",
    "total_count": 2,
    "attachment_count": 2,
    "importance_level": 0,
    "unread_count": 2
  },
  {
    "tags": [],
    "excerpt": "Les champignons gardent toute leur saveur quand ils",
    "privacy_index": 25,
    "participants": [
      {
        "address": "panoramix@caliopen.local",
        "contacts_ids": ["df71ff9d-026b-4d18-b555-b8d110c57069"],
        "protocol": "email",
        "label": "Panoramix",
        "type": "From"
      },
      {
        "address": "john@caliopen.local",
        "contact_ids": ["c-john-01"],
        "label": "Jaune",
        "protocol": "email",
        "type": "To"
      },
      {
        "address": "asterix@caliopen.local",
        "contacts_ids": ["2c8fb086-86da-4a87-9abc-668b73578f49"],
        "protocol": "email",
        "label": "Astérix",
        "type": "To"
      }
    ],
    "date_insert": "0042-09-08T15:00:00+00:00",
    "date_update": "0042-09-08T15:00:00+00:00",
    "discussion_id": "b1256c1e-7b65-4fe2-8960-a7d6c0c4a051",
    "last_message_id": "0bf58db0-b664-49e1-ade3-4f4e2424aa86",
    "last_message_subject": "Ils sont fous ces romains.",
    "total_count": 5,
    "attachment_count": 0,
    "importance_level": 7,
    "unread_count": 2
  },
  {
    "tags": [],
    "excerpt": "Moi, je verrais plutôt les champignons en salade…\n",
    "privacy_index": 1,
    "participants": [
      {
        "address": "agecanonix@caliopen.local",
        "contacts_ids": ["51cbcbbd-3b88-44f0-963a-06740e546c33"],
        "protocol": "email",
        "label": "Agecanonix",
        "type": "From"
      },
      {
        "address": "john@caliopen.local",
        "contact_ids": ["c-john-01"],
        "label": "foo",
        "protocol": "email",
        "type": "To"
      },
      {
        "address": "abraracourcix@caliopen.local",
        "contacts_ids": ["643fb7b3-c6fe-4f2b-9c0d-2ab671f482d5"],
        "protocol": "email",
        "label": "Abraracourcix",
        "type": "To"
      },
      {
        "address": "obelix@caliopen.local",
        "contacts_ids": ["629e086d-7257-49d7-9080-61cbb98b93ee"],
        "protocol": "email",
        "label": "Obélix",
        "type": "To"
      },
      {
        "address": "panoramix@caliopen.local",
        "contacts_ids": ["3e8769b9-77fb-4389-a00f-e2d1fd845fa1"],
        "protocol": "email",
        "label": "Panoramix",
        "type": "To"
      },
      {
        "address": "asterix@caliopen.local",
        "contacts_ids": ["2c8fb086-86da-4a87-9abc-668b73578f49"],
        "protocol": "email",
        "label": "Astérix",
        "type": "To"
      }
    ],
    "date_insert": "0042-09-08T14:32:00+00:00",
    "date_update": "0042-09-08T14:32:00+00:00",
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "last_message_id": "193e0cf8-fce8-4e26-8fe2-85858009b81d",
    "last_message_subject": "Ils sont fous ces romains.",
    "total_count": 8,
    "attachment_count": 0,
    "importance_level": 7,
    "unread_count": 9
  }
]


================================================
FILE: devtools/api-mock/discussions/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

export const actions = {
  get: createAction('Get discussions'),
  create: createAction('create discussion'),
};

const selectors = {
  all: () => (state) => state.discussions,
  byId: ({ discussion_id }) =>
    createSelector(selectors.all(), (discussions) => {
      const discussion = discussions.find(
        (discussion) => discussion.discussion_id === discussion_id
      );
      if (discussion) {
        return discussion;
      }

      throw new Error('discussion not found');
    }),
};

const reducer = {
  [actions.create]: (state, { body, req }) => {
    if (body.discussion_id) {
      return state;
    }

    const discussion = {
      discussion_id: uuidv1(),
      participants: body.participants.map((participant) => ({
        ...participant,
        protocol:
          participant.protocol === 'smtp' ? 'email' : participant.protocol,
      })),
      excerpt: body.body.slice(0, 100), // it works beccause created using POST message route
      privacy_index: 1,
      date_insert: new Date(),
      total_count: 1,
      attachment_count: 0,
      importance_level: 0,
      unread_count: 0,
    };

    // set discussionId for new draft;
    req.discussionId = discussion.discussion_id;

    return [...state, discussion];
  },
};

const routes = {
  'GET /': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
    middlewares: [createCollectionMiddleware('discussions')],
  },
  'GET /:discussion_id': {
    action: actions.get,
    selector: selectors.byId,
    status: 200,
  },
};

export default {
  name: 'discussions',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/discussions',
  routes: routes,
};


================================================
FILE: devtools/api-mock/local_identities/data.json
================================================
[
  {
    "credentials": {},
    "display_name": "Jown d'eau",
    "identity_id": "b7a715aa-8fff-4083-9dab-0c85b2634c0b",
    "identifier": "john@caliopen.local",
    "infos": {},
    "last_check": "0001-01-01T00:00:00Z",
    "protocol": "smtp",
    "status": "active",
    "type": "local",
    "user_id": "u-john-01"
  }
]


================================================
FILE: devtools/api-mock/local_identities/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

const actions = {
  get: createAction('Get local_identities'),
};

const selectors = {
  all: () => state => state.local_identities,
};

const reducer = {
  [actions.get]: state => state,
};

const routes = {
  'GET /': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
    middlewares: [createCollectionMiddleware('local_identities')],
  },
};

export default {
  name: 'local_identities',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/identities/locals',
  routes: routes,
};


================================================
FILE: devtools/api-mock/me/data.json
================================================
{
	"user_id": "u-john-01",
	"name": "Jaune",
	"given_name": "John Dœuf",
	"contact_id": "foobar112",
	"contact": {
	  "addresses": [],
	  "privacy_features": {},
	  "phones": [],
	  "contact_id": "c-john-01",
	  "date_insert": "2016-05-09T15:01:42.381000",
	  "identities": [],
	  "user_id": "u-john-01",
	  "title": "John",
	  "additional_name": "",
	  "date_update": null,
	  "organizations": [],
	  "ims": [],
	  "given_name": "John Dœuf",
	  "name_prefix": null,
	  "deleted": 0,
	  "pi": { "technic": 87, "context": 45, "comportment": 25 },
	  "tags": ["me"],
	  "infos": {
	    "birthday": "2016-05-09T15:01:42.11600"
	  },
	  "emails": [{
	    "email_id": "me-email",
	    "is_primary": 0,
	    "date_update": null,
	    "label": null,
	    "address": "john@caliopen.local",
	    "date_insert": "2016-05-09T15:01:42.116000",
	    "type": "home"
	  }],
	  "family_name": "Dœuf",
	  "name_suffix": null,
	  "avatar": "avatar.png",
	  "public_keys": []
	},
	"privacy_features": {
		"password_strength": "2"
	}
}


================================================
FILE: devtools/api-mock/me/index.js
================================================
import { createAction, createSelector } from 'bouchon';

const actions = {
  get: createAction('me'),
  patch: createAction('patch'),
  actions: createAction('actions'),
};

const selectors = {
  all: () => state => state.me,
};

const reducer = {
  [actions.get]: state => state,
};

const routes = {
  'GET /v1/me/': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
  },
  'PATCH /v2/users/:user_id/': {
    action: actions.patch,
    status: 204,
  },
  'POST /v2/users/:user_id/actions': {
    action: actions.actions,
    status: 204,
    middlewares: [data => (req, res, next) => {
      if (req.body.params.password !== '123456') {
        res.status(424);
        res.data = { errors: [{ message: '[RESTfacility] DeleteUser Wrong password' }]}
      }
      next();
    }],
  },
};

export default {
  name: 'me',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api',
  routes: routes,
};


================================================
FILE: devtools/api-mock/messages/data.json
================================================
[{
  "attachments": [],
  "body": "Fry! Stay back! He's too powerful! Can I use the gun? I barely knew Philip, but as a clergyman I have no problem telling his most intimate friends all about him. What are you hacking off? Is it my torso?! 'It is!' My precious torso!",
  "excerpt": "Fry! Stay back! He's too powerful! Can I use the gun? I barely knew Philip, but as a ...",
  "date": "2017-03-22T12:55:00.153000+00:00",
  "date_insert": "2017-03-21T12:55:00.153000+00:00",
  "date_sort": "2017-03-21T12:55:00.153000+00:00",
  "discussion_id": "cd53e13a-267d-4d9c-97ee-d0fc59c64200",
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "importance_level": 0,
  "is_answered": false,
  "is_draft": false,
  "is_received": false,
  "message_id": "11111111-267d-4d9c-97ee-d0fc59c64202",
  "participants": [{
  "address": "test@caliopen.local",
  "label": "foo",
  "protocol": "email",
  "type": "Cc"
  }, {
  "address": "john@caliopen.local",
  "contact_ids": ["c-john-01"],
  "label": "Jaune",
  "protocol": "email",
  "type": "From"
  }, {
  "address": "zoidberg@planet-express.tld",
  "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42fuie0"],
  "label": "zoidberg",
  "protocol": "email",
  "type": "To"
  }],
  "privacy_features": {},
  "raw_msg_id": "aaaaaaaa-267d-4d9c-97ee-d0fc59c64202",
  "tags": ["robot", "INBOX"],
  "protocol": "email",
  "pi": { "technic": 30, "context": 25, "comportment": 25, "version": 1 },
  "pi_message": { "transport": 30, "content": 25, "social": 25 },
  "user_id": ""
},
{
  "attachments": [],
  "body": "<p>It's okay, Bender. I like cooking too. You, minion. Lift my arm. AFTER H=\r\nIM! I don't know what you did, Fry, but once again, you screwed up! Now all\r\nthe planets are gonna start cracking wise abo",
  "excerpt": "It's okay, Bender. I like cooking too. You, minion. Lift my arm. AFTER HIM! I don't ...",
  "date": "2017-03-21T10:55:00.153000+00:00",
  "date_insert": "2017-03-21T10:55:00.153000+00:00",
  "date_sort": "2017-03-21T10:55:00.153000+00:00",
  "discussion_id": "cd53e13a-267d-4d9c-97ee-d0fc59c64200",
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "importance_level": 0,
  "is_answered": false,
  "is_draft": false,
  "is_received": true,
  "message_id": "11111111-267d-4d9c-97ee-d0fc59c64201",
  "participants": [{
  "address": "test@caliopen.local",
  "label": "foo",
  "protocol": "email",
  "type": "To"
  }, {
  "address": "john@caliopen.local",
  "contact_ids": ["c-john-01"],
  "label": "Jaune",
  "protocol": "email",
  "type": "Cc"
  }, {
  "address": "zoidberg@planet-express.tld",
  "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42fuie0"],
  "label": "zoidberg",
  "protocol": "email",
  "type": "From"
  }],
  "privacy_features": {},
  "raw_msg_id": "aaaaaaaa-267d-4d9c-97ee-d0fc59c64201",
  "subject": "It's okay, Bender. I like cooking too",
  "tags": ["robot", "IMPORTANT"],
  "protocol": "email",
  "pi": { "technic": 50, "context": 45, "comportment": 25, "version": 1 },
  "pi_message": { "transport": 50, "content": 45, "social": 25 },
  "user_id": ""
},
{
  "attachments": [],
  "body": "Shut up and take my money! Leela, are you alright? You got wanged on the he=\r\nad. Bender, you risked your life To save me! Spare me your space age techno=\r\nbabble, Attila the Hun! Now that the, uh, ga",
  "excerpt": "Shut up and take my money! Leela, are you alright? You got wanged on the head. Bender, ...",
  "date": "2017-03-21T10:55:00.153000+00:00",
  "date_insert": "2017-03-21T10:55:00.153000+00:00",
  "date_sort": "2017-03-21T10:55:00.153000+00:00",
  "discussion_id": "46d30c27-6cd8-407b-8536-fda4196c20ca",
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "importance_level": 0,
  "is_answered": false,
  "is_draft": false,
  "is_received": true,
  "message_id": "2222222-267d-4d9c-97ee-d0fc59c64201",
  "participants": [{
  "address": "john@caliopen.local",
  "contact_ids": ["c-john-01"],
  "label": "Jaune",
  "protocol": "email",
  "type": "To"
  }, {
  "address": "zoidberg@planet-express.tld",
  "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42fuie0"],
  "label": "zoidberg",
  "protocol": "email",
  "type": "To"
  },{
  "address": "fry@planet-express.tld",
  "contact_ids": ["92d3907a-eeui-4537-b229-85f1c9d197bb"],
  "label": "Fry",
  "protocol": "email",
  "type": "From"
  }],
  "privacy_features": {},
  "raw_msg_id": "bbbbbbbbb-267d-4d9c-97ee-d0fc59c64201",
  "subject": "Shut up and take my money",
  "tags": ["INBOX", "SPAM"],
  "protocol": "email",
  "pi": { "technic": 40, "context": 15, "comportment": 45, "version": 1 },
  "pi_message": { "transport": 40, "content": 15, "social": 45 }
},
{
  "attachments": [],
  "body": "first message to remove individually",
  "excerpt": "first message to remove individually",
  "date": "2017-03-21T10:55:00.153000+00:00",
  "date_insert": "2017-03-21T10:55:00.153000+00:00",
  "date_sort": "2017-03-20T10:55:00.153000+00:00",
  "discussion_id": "3330c27-6cd8-407b-8536-fda4196c20ca",
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "importance_level": 0,
  "is_answered": false,
  "is_draft": false,
  "is_received": true,
  "message_id": "3333-267d-4d9c-97ee-d0fc59c64201",
  "participants": [{
  "address": "john@caliopen.local",
  "contact_ids": ["c-john-01"],
  "label": "Jaune",
  "protocol": "email",
  "type": "To"
  }, {
  "address": "removeme@caliopen.local",
  "label": "remove message",
  "protocol": "email",
  "type": "From"
  }],
  "privacy_features": {},
  "raw_msg_id": "bbbbbbbbb-267d-4d9c-97ee-d0fc59c64201",
  "subject": "remove message one by one",
  "protocol": "email",
  "pi": { "technic": 50, "context": 45, "comportment": 25, "version": 1 },
  "pi_message": { "transport": 50, "content": 45, "social": 25 }
},
{
  "attachments": [],
  "body": "last message to remove individually",
  "excerpt": "last message to remove individually",
  "date": "2017-03-21T10:55:00.153000+00:00",
  "date_insert": "2017-03-21T10:55:00.153000+00:00",
  "date_sort": "2017-03-20T10:55:00.153000+00:00",
  "discussion_id": "3330c27-6cd8-407b-8536-fda4196c20ca",
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "importance_level": 0,
  "is_answered": false,
  "is_draft": false,
  "is_received": false,
  "message_id": "4444-267d-4d9c-97ee-d0fc59c64201",
  "participants": [{
  "address": "john@caliopen.local",
  "contact_ids": ["c-john-01"],
  "label": "Jaune",
  "protocol": "email",
  "type": "From"
  }, {
  "address": "removeme@caliopen.local",
  "label": "remove message",
  "protocol": "email",
  "type": "To"
  }],
  "privacy_features": {},
  "raw_msg_id": "bbbbbbbbb-267d-4d9c-97ee-d0fc59c64201",
  "subject": "remove message one by one",
  "protocol": "email",
  "pi": { "technic": 50, "context": 45, "comportment": 25, "version": 1 },
  "pi_message": { "transport": 50, "content": 45, "social": 25 }
},
{
  "attachments": [],
  "body": "a message of a collection to remove ",
  "excerpt": "a message of a collection to remove ",
  "date": "2017-03-21T10:55:00.153000+00:00",
  "date_insert": "2017-03-21T10:55:00.153000+00:00",
  "date_sort": "2017-03-20T10:55:00.153000+00:00",
  "discussion_id": "44440c27-6cd8-407b-8536-fda4196c20ca",
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "importance_level": 0,
  "is_answered": false,
  "is_draft": false,
  "is_received": true,
  "message_id": "5555-267d-4d9c-97ee-d0fc59c64201",
  "participants": [{
  "address": "john@caliopen.local",
  "contact_ids": ["c-john-01"],
  "label": "Jaune",
  "protocol": "email",
  "type": "To"
  }, {
  "address": "removeme@caliopen.local",
  "label": "remove message",
  "protocol": "email",
  "type": "From"
  }],
  "privacy_features": {},
  "raw_msg_id": "bbbbbbbbb-267d-4d9c-97ee-d0fc59c64201",
  "subject": "remove messages",
  "protocol": "email",
  "pi": { "technic": 50, "context": 45, "comportment": 25, "version": 1 },
  "pi_message": { "transport": 50, "content": 45, "social": 25 }
},
{
  "attachments": [],
  "body": "an other message of a collection to remove",
  "excerpt": "an other message of a collection to remove",
  "date": "2017-03-21T10:55:00.153000+00:00",
  "date_insert": "2017-03-21T10:55:00.153000+00:00",
  "date_sort": "2017-03-20T10:55:00.153000+00:00",
  "discussion_id": "44440c27-6cd8-407b-8536-fda4196c20ca",
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "importance_level": 0,
  "is_answered": false,
  "is_draft": false,
  "is_received": false,
  "message_id": "6666-267d-4d9c-97ee-d0fc59c64201",
  "participants": [{
  "address": "john@caliopen.local",
  "contact_ids": ["c-john-01"],
  "label": "Jaune",
  "protocol": "email",
  "type": "From"
  }, {
  "address": "removeme@caliopen.local",
  "label": "remove message",
  "protocol": "email",
  "type": "To"
  }],
  "privacy_features": {},
  "raw_msg_id": "bbbbbbbbb-267d-4d9c-97ee-d0fc59c64201",
  "subject": "remove message one by one",
  "protocol": "email",
  "pi": { "technic": 50, "context": 45, "comportment": 25, "version": 1 },
  "pi_message": { "transport": 50, "content": 45, "social": 25 }
},
{
  "attachment": [],
  "discussion_id": "b1256c1e-7b65-4fe2-8960-a7d6c0c4a051",
  "message_id": "74488b21-318c-4c60-be21-36cea07cfde2",
  "is_answered": true,
  "is_draft": false,
  "is_received": true,
  "importance_level": 0,
  "privacy_features": {},
  "raw_msg_id": "1ac9a18b-2453-45e7-b778-528043de4373",
  "subject": "Ils sont fous ces romains.",
  "protocol": "twitter",
  "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
  "pi_message": { "transport": 30, "content": 10, "social": 1 },
  "participants": [
    {
      "address": "john@caliopen.local",
      "contact_ids": [
        "c-john-01"
      ],
      "label": "foo",
      "protocol": "email",
      "type": "From"
    },
    {
      "address": "panoramix@caliopen.local",
      "contacts_ids": [
        "fedd1cc7-2db3-442f-a42a-24e21e98ff52"
      ],
      "protocol": "email",
      "label": "Panoramix",
      "type": "To"
    },
    {
      "address": "asterix@caliopen.local",
      "contacts_ids": [
        "2c8fb086-86da-4a87-9abc-668b73578f49"
      ],
      "protocol": "email",
      "label": "Astérix",
      "type": "To"
    }
  ],
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "body": "Ils sont fous, ces gaulois.\n",
  "excerpt": "Ils sont fous, ces gaulois.",
  "date": "0042-09-08T14:55:00+00:00",
  "date_insert": "0042-09-08T15:00:00+00:00",
  "date_sort": "0042-09-08T15:00:00+00:00"
},
{
  "attachment": [],
  "discussion_id": "b1256c1e-7b65-4fe2-8960-a7d6c0c4a051",
  "message_id": "74488b21-318c-4c60-be21-36cea07cfde2",
  "is_answered": true,
  "is_draft": false,
  "is_received": true,
  "importance_level": 0,
  "privacy_features": {},
  "raw_msg_id": "1ac9a18b-2453-45e7-b778-528043de4373",
  "subject": "Ils sont fous ces romains.",
  "type": "email",
  "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
  "pi_message": { "transport": 30, "content": 10, "social": 1 },
  "participants": [
      {
          "address": "panoramix@caliopen.local",
          "contacts_ids": [
						"fedd1cc7-2db3-442f-a42a-24e21e98ff52"
          ],
          "protocol": "email",
          "label": "Panoramix",
          "type": "From"
      },
      {
          "address": "john@caliopen.local",
          "contact_ids": [
              "c-john-01"
          ],
          "label": "foo",
          "protocol": "email",
          "type": "To"
      },
      {
          "address": "asterix@caliopen.local",
          "contacts_ids": [
              "2c8fb086-86da-4a87-9abc-668b73578f49"
          ],
          "protocol": "email",
          "label": "Astérix",
          "type": "To"
      }
  ],
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "body": "Les champignons gardent toute leur saveur quand ils sont sautés.\n",
  "excerpt": "Les champignons gardent toute leur saveur quand ils",
  "date": "0042-09-08T14:55:00+00:00",
  "date_insert": "0042-09-08T15:00:00+00:00",
  "date_sort": "0042-09-08T15:00:00+00:00"
},
{
  "attachment": [],
  "discussion_id": "b1256c1e-7b65-4fe2-8960-a7d6c0c4a051",
  "message_id": "0bf58db0-b664-49e1-ade3-4f4e2424aa86",
  "is_answered": true,
  "is_draft": false,
  "is_received": true,
  "importance_level": 0,
  "privacy_features": {},
  "raw_msg_id": "ebcdb6b2-ffac-4360-a9e7-cb44a091bc06",
  "subject": "Ils sont fous ces romains.",
  "protocol": "email",
  "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
  "pi_message": { "transport": 30, "content": 10, "social": 1 },
  "participants": [
      {
          "address": "panoramix@caliopen.local",
          "contacts_ids": [
              "df71ff9d-026b-4d18-b555-b8d110c57069"
          ],
          "protocol": "email",
          "label": "Panoramix",
          "type": "From"
      },
      {
          "address": "john@caliopen.local",
          "contact_ids": [
              "c-john-01"
          ],
          "label": "Jaune",
          "protocol": "email",
          "type": "To"
      },
      {
          "address": "asterix@caliopen.local",
          "contacts_ids": [
              "2c8fb086-86da-4a87-9abc-668b73578f49"
          ],
          "protocol": "email",
          "label": "Astérix",
          "type": "To"
      }
  ],
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "body": "Il faut les faire sauter !\n",
  "excerpt": "Il faut les faire sauter !\n",
  "date": "0042-09-08T14:49:00+00:00",
  "date_insert": "0042-09-08T14:53:00+00:00",
  "date_sort": "0042-09-08T14:53:00+00:00"
},
{
  "attachment": [],
  "discussion_id": "b1256c1e-7b65-4fe2-8960-a7d6c0c4a051",
  "message_id": "956e52a5-5d73-4838-8d95-f5006973457c",
  "is_answered": true,
  "is_draft": false,
  "is_received": true,
  "importance_level": 0,
  "privacy_features": {},
  "raw_msg_id": "3ca3f788-8ba0-4b96-9f54-b5625d1c1a83",
  "subject": "Ils sont fous ces romains.",
  "protocol": "email",
  "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
  "pi_message": { "transport": 30, "content": 10, "social": 1 },
  "participants": [
      {
          "address": "asterix@caliopen.local",
          "contacts_ids": [
              "8165f843-c5c7-4409-9cc9-59054688d3cd"
          ],
          "protocol": "email",
          "label": "Astérix",
          "type": "From"
      },
      {
          "address": "john@caliopen.local",
          "contact_ids": [
              "c-john-01"
          ],
          "label": "Jaune",
          "protocol": "email",
          "type": "To"
      },
      {
          "address": "panoramix@caliopen.local",
          "contacts_ids": [
              "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
          ],
          "protocol": "email",
          "label": "Panoramix",
          "type": "To"
      }
  ],
  "user_identities": ["aaaa-bbbb-cccc-ddd1"],
  "body": "Alors qu'allons-nous faire, ô Druide ?\n",
  "excerpt": "Alors qu'allons-nous faire, ô Druide ?\n",
  "date": "0042-09-08T14:40:00+00:00",
  "date_insert": "0042-09-08T14:45:00+00:00",
  "date_sort": "0042-09-08T14:45:00+00:00"
},
{
	"attachment": [],
	"discussion_id": "b1256c1e-7b65-4fe2-8960-a7d6c0c4a051",
	"message_id": "a0da20e1-0829-4f0f-b44a-7417177b4f4e",
	"is_answered": true,
	"is_draft": false,
	"is_received": true,
	"importance_level": 0,
	"privacy_features": {},
	"raw_msg_id": "0355031c-2ef7-4683-b75a-8b6b9a13f4f9",
	"subject": "Ils sont fous ces romains.",
	"protocol": "email",
	"pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
	"pi_message": { "transport": 30, "content": 10, "social": 1 },
	"participants": [
		{
			"address": "panoramix@caliopen.local",
			"contacts_ids": [
				"fd7bb4dd-9166-4e1b-86eb-cbcbddde23e8"
			],
			"protocol": "email",
			"label": "Panoramix",
			"type": "From"
		},
		{
			"address": "john@caliopen.local",
			"contact_ids": [
				"c-john-01"
			],
			"label": "Jaune",
			"protocol": "email",
			"type": "To"
		},
		{
			"address": "asterix@caliopen.local",
			"contacts_ids": [
				"2c8fb086-86da-4a87-9abc-668b73578f49"
			],
			"protocol": "email",
			"label": "Astérix",
			"type": "To"
		}
	],
	"user_identities": ["aaaa-bbbb-cccc-ddd1"],
	"body": "Parfois, j'ai l'impression que nos amis ne sont pas très sérieux… La bonne humeur des romains est peut-être mauvais signe pour nous.\n",
	"excerpt": "Parfois, j'ai l'impression que nos amis ne sont pas",
	"date": "0042-09-08T14:33:00+00:00",
	"date_insert": "0042-09-08T14:39:00+00:00",
	"date_sort": "0042-09-08T14:39:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "193e0cf8-fce8-4e26-8fe2-85858009b81d",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "6bb23fb9-6947-43b7-9b86-96207decabcd",
    "subject": "Ils sont fous ces romains.",
    "protocol": "twitter",
    "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
    "pi_message": { "transport": 30, "content": 10, "social": 1 },
    "participants": [
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "51cbcbbd-3b88-44f0-963a-06740e546c33"
            ],
            "protocol": "email",
            "label": "Agecanonix mais avec un nom très très très très long",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "643fb7b3-c6fe-4f2b-9c0d-2ab671f482d5"
            ],
            "protocol": "email",
            "label": "Abraracourcix",
            "type": "To"
        },
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "629e086d-7257-49d7-9080-61cbb98b93ee"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "To"
        },
        {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "Moi, je verrais plutôt les champignons en salade…\n",
    "excerpt": "Moi, je verrais plutôt les champignons en salade…\n",
    "date": "0042-09-08T14:27:00+00:00",
    "date_insert": "0042-09-08T14:32:00+00:00",
    "date_sort": "0042-09-08T14:32:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "e39919d5-d1cb-4887-8a42-95755a79f8b9",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "bd29b3cf-7dec-423c-96f3-b1406c483984",
    "subject": "Ils sont fous ces romains. Malheureusement ce sujet est trop long pour s'afficher sur une ligne",
    "protocol": "email",
    "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
    "pi_message": { "transport": 30, "content": 10, "social": 1 },
    "participants": [
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "592a4bdb-085a-4e73-9aa8-fa3b41518b4b"
            ],
            "protocol": "email",
            "label": "Abraracourcix but with a very long name",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "25e6de4d-eadb-434a-a12c-16a127e93c03"
            ],
            "protocol": "email",
            "label": "Agecanonix",
            "type": "To"
        },
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "629e086d-7257-49d7-9080-61cbb98b93ee"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "To"
        },
        {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "Rien du tout ! Je suis le chef, justement ! Nous ferons une omelette !\n J'ai aussi un extrementabusémentlongquidépassedelécransursmartphone et voilà",
    "excerpt": "Rien du tout ! Je suis le chef, justement ! Nous fe",
    "date": "0042-09-08T14:19:00+00:00",
    "date_insert": "0042-09-08T14:24:00+00:00",
    "date_sort": "0042-09-08T14:24:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "8fc1481d-5e06-463f-86f2-27ffbc2e1ef8",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "dfb61e77-6bb7-45e6-826c-82622b617021",
    "subject": "Ils sont fous ces romains.",
    "type": "facebook",
    "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
    "pi_message": { "transport": 30, "content": 10, "social": 1 },
    "participants": [
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "9c046b01-bc65-4769-aefc-3b0580ca9ab3"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "25e6de4d-eadb-434a-a12c-16a127e93c03"
            ],
            "protocol": "email",
            "label": "Agecanonix",
            "type": "To"
        },
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "643fb7b3-c6fe-4f2b-9c0d-2ab671f482d5"
            ],
            "protocol": "email",
            "label": "Abraracourcix",
            "type": "To"
        },
        {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "Mais Abraracourcix notre chef…\n",
    "excerpt": "Mais Abraracourcix notre chef…\n",
    "date": "0042-09-08T14:12:00+00:00",
    "date_insert": "0042-09-08T14:16:00+00:00",
    "date_sort": "0042-09-08T14:16:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "9510f8ee-7701-4a23-bc82-4c9ae5c47778",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "11025bc2-3513-44bf-9228-e73fa7474236",
    "subject": "Ils sont fous ces romains.",
    "protocol": "email",
    "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
    "pi_message": { "transport": 30, "content": 10, "social": 1 },
    "participants": [
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "18c156dc-9781-4851-abe6-f6966cdcaf38"
            ],
            "protocol": "email",
            "label": "Abraracourcix",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "25e6de4d-eadb-434a-a12c-16a127e93c03"
            ],
            "protocol": "email",
            "label": "Agecanonix",
            "type": "To"
        },
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "629e086d-7257-49d7-9080-61cbb98b93ee"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "To"
        },
        {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "C'est une omelette qu'il faut faire avec les champignons. Un vrai gourmet les mange en omelette !\n",
    "excerpt": "C'est une omelette qu'il faut faire avec les champi",
    "date": "0042-09-08T14:05:00+00:00",
    "date_insert": "0042-09-08T14:10:00+00:00",
    "date_sort": "0042-09-08T14:10:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "de45139c-a74c-45b0-9f48-a75e0e568e6a",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "4a1fa14c-be6d-41b3-947b-4eda3718050b",
    "subject": "Ils sont fous ces romains.",
    "type": "sms",
    "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
    "pi_message": { "transport": 30, "content": 10, "social": 1 },
    "participants": [
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "17bc2dde-e283-4800-8c84-abf55f372121"
            ],
            "protocol": "email",
            "label": "Abraracourcix",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "25e6de4d-eadb-434a-a12c-16a127e93c03"
            ],
            "protocol": "email",
            "label": "Agecanonix",
            "type": "To"
        },
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "629e086d-7257-49d7-9080-61cbb98b93ee"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "To"
        },
        {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "DE LA SOUPE ?!… C'EST TOUT CE QUE TU TROUVE À DIRE OBÉLIX ?!…\n",
    "excerpt": "DE LA SOUPE ?!… C'EST TOUT CE QUE TU TROUVE À DIRE ",
    "date": "0042-09-08T13:58:00+00:00",
    "date_insert": "0042-09-08T14:02:00+00:00",
    "date_sort": "0042-09-08T14:02:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "3202d2ee-9192-42a9-8330-b92297a885eb",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "fbeb7ad7-b0b4-4508-a7c5-48cba66a3628",
    "subject": "Ils sont fous ces romains.",
    "type": "facebook",
    "pi": { "technic": 10, "context": 10, "comportment": 40, "version": 1 },
    "pi_message": { "transport": 10, "content": 10, "social": 40 },
    "participants": [
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "a836fea1-2e4a-49eb-9e0b-a25bd19c3902"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "25e6de4d-eadb-434a-a12c-16a127e93c03"
            ],
            "protocol": "email",
            "label": "Agecanonix",
            "type": "To"
        },
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "643fb7b3-c6fe-4f2b-9c0d-2ab671f482d5"
            ],
            "protocol": "email",
            "label": "Abraracourcix",
            "type": "To"
        },
        {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "De la soupe. Avec les champignons, il faut faire de la soupe, c'est bon.\n",
    "excerpt": "De la soupe. Avec les champignons, il faut faire de",
    "date": "0042-09-08T13:54:00+00:00",
    "date_insert": "0042-09-08T13:55:00+00:00",
    "date_sort": "0042-09-08T13:55:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "29b35424-f861-437a-b019-93c9eece1618",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "16817826-6fd8-4ff8-83b6-5cd93c4402fa",
    "subject": "Ils sont fous ces romains.",
    "protocol": "twitter",
    "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
    "pi_message": { "transport": 30, "content": 10, "social": 1 },
    "participants": [
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "6b006c4f-782a-43b8-803e-518a8d7984a8"
            ],
            "protocol": "email",
            "label": "Abraracourcix",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "25e6de4d-eadb-434a-a12c-16a127e93c03"
            ],
            "protocol": "email",
            "label": "Agecanonix",
            "type": "To"
        },
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "629e086d-7257-49d7-9080-61cbb98b93ee"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "To"
        },
  {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "Hmm… C'est étrange, ça, Agecanonix… Qu'allons-nous faire ?\n",
    "excerpt": "Hmm… C'est étrange, ça, Agecanonix, qu'allons-nous ",
    "date": "0042-09-08T13:47:00+00:00",
    "date_insert": "0042-09-08T13:50:00+00:00",
    "date_sort": "0042-09-08T13:50:00+00:00"
},
{
    "attachment": [],
    "discussion_id": "37e376ce-8be4-453c-a3bf-86eefaff1940",
    "message_id": "38366a81-d890-4767-a8ba-c0e54c5c223c",
    "is_answered": true,
    "is_draft": false,
    "is_received": true,
    "importance_level": 0,
    "privacy_features": {},
    "raw_msg_id": "731594dd-e94f-4186-ac0d-d1ac5351df5d",
    "subject": "Ils sont fous ces romains.",
    "protocol": "twitter",
    "pi": { "technic": 30, "context": 10, "comportment": 1, "version": 1 },
    "pi_message": { "transport": 30, "content": 10, "social": 1 },
    "participants": [
        {
            "address": "agecanonix@caliopen.local",
            "contacts_ids": [
                "6708a18a-a6c5-491b-b1f3-985b4c3d638a"
            ],
            "protocol": "email",
            "label": "Agecanonix",
            "type": "From"
        },
        {
            "address": "john@caliopen.local",
            "contact_ids": [
                "c-john-01"
            ],
            "label": "Jaune",
            "protocol": "email",
            "type": "To"
        },
        {
            "address": "abraracourcix@caliopen.local",
            "contacts_ids": [
                "643fb7b3-c6fe-4f2b-9c0d-2ab671f482d5"
            ],
            "protocol": "email",
            "label": "Abraracourcix",
            "type": "To"
        },
        {
            "address": "obelix@caliopen.local",
            "contacts_ids": [
                "629e086d-7257-49d7-9080-61cbb98b93ee"
            ],
            "protocol": "email",
            "label": "Obélix",
            "type": "To"
        },
        {
            "address": "panoramix@caliopen.local",
            "contacts_ids": [
                "3e8769b9-77fb-4389-a00f-e2d1fd845fa1"
            ],
            "protocol": "email",
            "label": "Panoramix",
            "type": "To"
        },
        {
            "address": "asterix@caliopen.local",
            "contacts_ids": [
                "2c8fb086-86da-4a87-9abc-668b73578f49"
            ],
            "protocol": "email",
            "label": "Astérix",
            "type": "To"
        }
    ],
    "user_identities": ["aaaa-bbbb-cccc-ddd1"],
    "body": "J'étais en train de cueillir des champignons du côté d'Aquarium, —ils sont bons, là-bas— quand j'ai entendu des cris de joie… Les romains ont l'air de très bonne humeur !\n",
    "excerpt": "J'étais en train de cueillir des champignons du côt",
    "date": "0042-09-08T13:37:00+00:00",
    "date_insert": "0042-09-08T13:43:00+00:00",
    "date_sort": "0042-09-08T13:43:00+00:00"
}
]


================================================
FILE: devtools/api-mock/messages/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v4 as uuidv4 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';
import { actions as discussionActions } from '../discussions';

const actions = {
  get: createAction('Get messages'),
  post: createAction('Post message'),
  patch: createAction('Patch message'),
  delete: createAction('Delete message'),
  actions: createAction('Actions message'),
  patchTags: createAction('Patch message\'s tags'),
};

const notifiedMessageIds = '12345'.split('').map((v) => `1aaa-bbbb-000${v}`);

const getMessageFromNotifier = (messageId) => {
  if (notifiedMessageIds.includes(messageId)) {
    const now = new Date();

    return {
      attachments: [],
      body: `notif ${messageId}`,
      excerpt: `notif ${messageId}`,
      date: now.toISOString(),
      date_insert: now.toISOString(),
      date_sort: now.toISOString(),
      discussion_id: 'cd53e13a-267d-4d9c-97ee-d0fc59c64200',
      user_identities: ['aaaa-bbbb-cccc-ddd1'],
      importance_level: 0,
      is_answered: false,
      is_draft: false,
      is_received: false,
      message_id: messageId,
      participants: [{
        address: 'test@caliopen.local',
        label: 'foo',
        protocol: 'email',
        type: 'Cc'
      }, {
        address: 'john@caliopen.local',
        contact_ids: ['c-john-01'],
        label: 'Jaune',
        protocol: 'email',
        type: 'From'
      }, {
        address: 'zoidberg@planet-express.tld',
        contact_ids: ['0ba2e346-e4f8-4c45-9adc-eeb1d42fuie0'],
        label: 'zoidberg',
        protocol: 'email',
        type: 'To'
      }],
    };
  }

  return undefined;
}


const selectors = {
  all: () => state => state.messages,
  last: () => state => [...state.messages].pop(),
  byQuery: ({ offset = 0, limit = 20, discussion_id, is_draft, is_received }) => createSelector(
    [discussion_id ? selectors.byDiscussionId({ discussion_id }) :  selectors.all()],
    messages => {
      const end = new Number(offset) + new Number(limit);
      return messages.filter(message => {
        if (is_draft !== undefined && message.is_draft.toString() !== is_draft) {
          return false;
        }
        if (is_received !== undefined && message.is_received.toString() !== is_received) {
          return false;
        }
        return true;
      }).slice(offset, end);
    }
  ),
  byDiscussionId: ({ discussion_id }) => createSelector(
    selectors.all(),
    messages => messages.filter(message => message.discussion_id === discussion_id)
  ),
  lastLocation: () => createSelector(
    selectors.last(),
    message => ({ location: `/api/v2/messages/${message.message_id}` })
  ),
  byId: ({ message_id }) => createSelector(
    selectors.all(),
    messages => {
      let result = messages.find(message => message.message_id === message_id);

      if (!result) {
        result = getMessageFromNotifier(message_id);
      }

      return result;
    }
  ),
};

const filterAuthor = participants => participants.filter(participant => participant.type !== 'From');
const reduceParticipants = message => [
  ...(message.participants ? filterAuthor(message.participants) : []),
  {
    address: 'john@caliopen.local',
    contact_ids: ['c-john-01'],
    label: 'Jaune john',
    protocol: 'email',
    type: 'From'
  },
];

const reducer = {
  [actions.get]: state => state.sort((a, b) => new Date(b.date_sort) - new Date(a.date_sort)),
  [actions.post]: (state, { body, req: { discussionId } }) => ([
    ...state,
    {
      discussion_id: discussionId,
      ...body,
      excerpt: body.body.slice(0, 30) + '...',
      message_id: body.message_id || uuidv4(),
      is_draft: true,
      is_unread: false,
      is_received: false,
      date: Date.now(),
      date_insert: Date.now(),
      date_sort: Date.now(),
      pi: { technic: 50, context: 45, comportment: 25, version: 1 },
      pi_message: { transport: 50, content: 45, social: 25 },
      participants: reduceParticipants(body),
    },
  ]),
  [actions.patch]: (state, { params, body }) => {
    const nextState = [...state];
    const original = state.find(message => message.message_id === params.message_id);
    if (!original) {
      throw `message w/ id ${params.message_id} not found`;
    }
    const index = nextState.indexOf(original);
    const { current_state, ...props } = body;
    nextState[index] = {
      ...original,
      ...props,
      participants: state[index].is_draft ? reduceParticipants(props) : nextState[index].participants,
    };

    return nextState;
  },
  [actions.delete]: (state, { params, body }) => {
    const original = state.find(message => message.message_id === params.message_id);
    if (!original) {
      throw `message w/ id ${params.message_id} not found`;
    }

    return [...state.filter(message => message.message_id !== params.message_id)];
  },
  [actions.patchTags]: (state, { params, body }) => {
    const original = state.find(message => message.message_id === params.message_id);
    if (!original) {
      throw `message w/ id ${params.message_id} not found`;
    }

    const index = state.indexOf(original);
    const nextState = [...state];
    const { tags } = body;

    nextState[index] = {
      ...original,
      tags,
    };

    return nextState;
  },
  [actions.actions]: (state, { params, body }) => {
    const original = state.find(message => message.message_id === params.message_id);
    if (!original) {
      throw `message w/ id ${params.message_id} not found`;
    }
    const index = state.indexOf(original);

    return body.actions.reduce((acc, action) => {
      switch (action) {
        case 'send':
          acc[index] = { ...acc[index], is_draft: false, date: Date.now() };

          return acc;
        case 'set_read':
          acc[index] = { ...acc[index], is_unread: false };

          return acc;
        case 'set_unread':
          acc[index] = { ...acc[index], is_unread: true };

          return acc;
        default:
          throw new Error(`Unexpected action "${action}"`);
      }
    }, [...state]);
  },
};

const routes = {
  'GET /v2/messages/': {
    action: actions.get,
    selector: selectors.byQuery,
    status: 200,
    middlewares: [createCollectionMiddleware('messages')],
  },
  'GET /v2/messages/:message_id': {
    action: actions.get,
    selector: selectors.byId,
    status: 200,
    middlewares: [data => (req, res, next) => {
      if (!data) {
        res.status(404);
      }
    }],
  },
  'DELETE /v1/messages/:message_id': {
    action: actions.delete,
    status: 204,
  },
  'POST /v2/messages/:message_id/actions': {
    action: actions.actions,
    selector: selectors.byId,
    status: 200,
  },
  'PATCH /v2/messages/:message_id/tags': {
    action: actions.patchTags,
    status: 204,
  },
  'POST /v1/messages/': {
    action: [discussionActions.create, actions.post],
    selector: selectors.lastLocation,
    status: 200,
  },
  'PATCH /v1/messages/:message_id': {
    action: actions.patch,
    status: 204,
  },
};

export default {
  name: 'messages',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api',
  routes: routes,
};


================================================
FILE: devtools/api-mock/notifications/data.json
================================================
{
  "total": 4,
  "notifications": [
    {
      "emitter": "imap_worker",
      "notif_id": "aaaa-bbbb-0001",
      "type": "new_message",
      "body": {
        "size": 666
      }
    },
    {
      "emitter": "imap_worker",
      "notif_id": "aaaa-bbbb-0002",
      "type": "new_message",
      "body": {
        "size": 1,
        "elements": [
          { "body": { "message_id": "1aaa-bbbb-0001", "discussion_id": "" } }
        ]
      }
    },
    {
      "emitter": "contacts",
      "notif_id": "aaaa-bbbb-0003",
      "body": "success",
      "type": "event",
      "user_id": "u-john-01"
    },
    {
      "emitter": "imap_worker",
      "notif_id": "aaaa-bbbb-0004",
      "type": "new_message",
      "body": {
        "size": 3,
        "elements": [
          { "body": { "message_id": "1aaa-bbbb-0002", "discussion_id": "" } },
          { "body": { "message_id": "1aaa-bbbb-0003", "discussion_id": "" } },
          { "body": { "message_id": "1aaa-bbbb-0005", "discussion_id": "" } }
        ]
      }
    }
  ]
}


================================================
FILE: devtools/api-mock/notifications/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

import initialData from './data.json';

const actions = {
  get: createAction('Get notifications'),
  delete: createAction('Delete notifications'),
  resetDev: createAction('Reset fixtures for dev purposes (see tests)'),
};

const selectors = {
  all: () => state => state.notifications,
};

const reducer = {
  [actions.delete]: (state) => {
    return {
      ...state,
      total: 0,
      notifications: [],
    };
  },
  [actions.resetDev]: () => {
    return {
      ...initialData,
    };
  },
};

const routes = {
  'GET': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
  },
  'DELETE': {
    action: actions.delete,
    status: 204,
  },
  'GET /reset-dev': {
    action: actions.resetDev,
    status: 200,
  },
};

export default {
  name: 'notifications',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/notifications',
  routes: routes,
};


================================================
FILE: devtools/api-mock/oauth-mock/data.json
================================================
[]


================================================
FILE: devtools/api-mock/oauth-mock/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { actions as remoteIdentActions } from '../remote_identities';

const actions = {
  get: createAction('Get remote_identities'),
};

const routes = {
  'GET /:providerName': {
    action: [remoteIdentActions.createOauth, actions.get],
    status: 200,
    middlewares: [data => (req, res, next) => {
      const providerName = req.params.providerName;

      switch (providerName) {
        case 'gmail':
        case 'twitter':
          res.send(`<div><a href="/api/v2/providers/${providerName}/callback">authorize ${providerName}</a></div>`);
          break;
        default:
          throw new Error('provider not found');
      }
    }],
  },
};

export default {
  name: 'oauth-mock',
  endpoint: '/api/oauth-mock',
  routes: routes,
};


================================================
FILE: devtools/api-mock/package.json
================================================
{
  "name": "api-mock",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "babel-core": "^6.24.0",
    "babel-polyfill": "^6.23.0",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-stage-2": "^6.22.0",
    "bouchon": "^0.4.0",
    "uuid": "^3.0.1"
  },
  "scripts": {
    "start": "bouchon -d . -p 31415"
  },
  "babel": {
    "presets": [
      "es2015",
      "stage-2"
    ]
  }
}


================================================
FILE: devtools/api-mock/participants/data.json
================================================
[{
  "address": "bender@caliopen.local",
  "contact_id": "92d3727a-eefc-4537-b879-85f1c9d197bb",
  "label": "Bender",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "zoidberg@caliopen.local",
  "contact_id": "0ba2e346-e4f8-4c45-9adc-eeb1d42fuie0",
  "label": "Zoidberg",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "@bender",
  "contact_id": "92d3727a-eefc-4537-b879-85f1c9d197bb",
  "label": "@Bender",
  "protocol": "twitter",
  "source": "contact"
}, {
  "address": "@zoidberg",
  "contact_id": "0ba2e346-e4f8-4c45-9adc-eeb1d42fuie0",
  "label": "@Zoidberg",
  "protocol": "twitter",
  "source": "contact"
}, {
  "address": "leela@john.doe",
  "contact_id": "19c3ui42-e3ba-46e7-984f-4c3e8de11c05",
  "label": "Leela",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "fry@caliopen.local",
  "contact_id": "92d3907a-eeui-4537-b229-85f1c9d197bb",
  "label": "Fry",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "amy@caliopen.local",
  "contact_id": "0ba2e346-e4f8-4c45-999c-eeb1d42f07e0",
  "label": "Amy",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "professor@planet.express",
  "contact_id": "19c3ce42-e3ba-46e7-902f-4cui8de11c05",
  "label": "Farnsworth",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "lrrr@caliopen.local",
  "contact_id": "9ui3907a-eefc-4537-b229-85f1c9d197bb",
  "label": "Lrrr",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "stephen@caliopen.local",
  "contact_id": "98o3907a-eefc-6724-bv28-85f1c9d197bb",
  "label": "Stephen Hawking",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "kroker@caliopen.local",
  "contact_id": "0327707a-eefc-6724-bv28-85f1c9d197bb",
  "label": "Kif",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "zapp@caliopen.local",
  "contact_id": "5488707a-eefc-6724-bv28-85f1c9d197bb",
  "label": "Zapp Brannigan",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "francine@doop",
  "contact_id": "19c3ce42-e3ba-46e7-902f-4cui8d",
  "label": "Elzar",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "algore@caliopen.local",
  "contact_id": "a3ce42-e3ba-46e7-902f-4cfdsfsui8d",
  "label": "Scruffy",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "Conrad@caliopen.local",
  "contact_id": "a3ce42-e3ba-46e7-dfsd902f-4cui8d",
  "label": "Hermès",
  "protocol": "email",
  "source": "contact"
}, {
  "address": "flexo@caliopen.local",
  "label": "Flexo",
  "protocol": "email",
  "source": "participant"
}, {
  "address": "calc@caliopen.local",
  "label": "Calculon",
  "protocol": "email",
  "source": "participant"
}, {
  "address": "mom@john.doe",
  "label": "Mom",
  "protocol": "email",
  "source": "participant"
}, {
  "address": "morbo@caliopen.local",
  "label": "Morbo the Annihilator",
  "protocol": "email",
  "source": "participant"
}, {
  "address": "Panucci@caliopen.local",
  "label": "Panucci",
  "protocol": "email",
  "source": "participant"
}, {
  "address": "nib@planet.express",
  "label": "Nibbler",
  "protocol": "email",
  "source": "participant"
}, {
  "address": "Hypnotoad@caliopen.local",
  "label": "Hypnotoad",
  "protocol": "email",
  "source": "participant"
}]


================================================
FILE: devtools/api-mock/participants/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

const actions = {
};

const match = ({ item, props, searchTerms }) => props.find(propName =>
      item[propName] && item[propName].toLowerCase().includes(searchTerms.toLowerCase()));

const selectors = {
  all: () => state => state.participants,
  byQuery: ({ context, q }) => createSelector(
    selectors.all(),
    participants => participants.filter(item => match({
      item, searchTerms: q, props: ['address', 'label'],
    }))
  ),
};

const reducer = {
};

const routes = {
  'GET /suggest': {
    action: actions.get,
    selector: selectors.byQuery,
    status: 200,
  },
};

export default {
  name: 'participants',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/participants',
  routes: routes,
};


================================================
FILE: devtools/api-mock/providers/data.json
================================================
[
  {
    "infos": {
      "client_id": "",
      "client_secret": "",
      "imapserver": "imap.gmail.com:993",
      "smtpserver": "smtp.gmail.com:465"
    },
    "name": "gmail",
    "protocol": "email",
    "Capabilities": null,
    "FetchItems": null
  },
  {
    "infos": {
      "consumer_key": "",
      "consumer_secret": ""
    },
    "name": "twitter",
    "protocol": "twitter",
    "Capabilities": null,
    "FetchItems": null
  },
  {
    "infos": {
      "consumer_key": "",
      "consumer_secret": ""
    },
    "name": "mastodon",
    "protocol": "mastodon",
    "Capabilities": null,
    "FetchItems": null
  }
]


================================================
FILE: devtools/api-mock/providers/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

const actions = {
  get: createAction('Get provider'),
  postRemote: createAction('post remote_identities'),
};

const twitterPopupUrl = 'https://api.twitter.com/oauth/authorize?oauth_token=<token>';
const oauthUrlCallbackHost = ''; // should be hardcoded but it can be localhost:4000 or test-frontend:4000 according to current test env

const selectors = {
  all: () => state => state.providers,
  byId: ({ providerName }) => createSelector(
    selectors.all(),
    providers => {
      const result = providers.find(provider => provider.name === providerName);

      if (!result) {
        throw new Error('provider not found');
      }

      return {
        ...result,
        oauth_callback_uri: `/api/v2/providers/${providerName}/callback`,
        oauth_request_url: `${oauthUrlCallbackHost}/api/oauth-mock/${providerName}`,
      };
    }
  ),
  none: () => state => {},
};

const reducer = {
};

const routes = {
  'GET /': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
    middlewares: [createCollectionMiddleware('providers')],
  },
  'GET /:providerName/callback': {
    selector: selectors.none,
    status: 200,
  },
  'GET /:providerName': {
    action: actions.get,
    selector: selectors.byId,
    status: 200,
  },
};

export default {
  name: 'providers',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/providers',
  routes: routes,
};


================================================
FILE: devtools/api-mock/remote_identities/data.json
================================================
[]


================================================
FILE: devtools/api-mock/remote_identities/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

export const actions = {
  get: createAction('Get remote_identities'),
  post: createAction('post remote_identities'),
  createOauth: createAction('post remote_identities'),
  patch: createAction('patch remote_identities'),
  delete: createAction('delete remote_identities'),
};

const selectors = {
  all: () => state => state.remote_identities,
  last: () => state => [...state.remote_identities].pop(),
  lastLocation: () => createSelector(
    selectors.last(),
    ({ identity_id }) => ({
      location: `/api/v2/remote_identity/${identity_id}`,
      identity_id,
      // FIXME: to del; backend inconsistency for now
      remote_id: identity_id,
    })
  ),
  byId: ({ identity_id }) => createSelector(
    selectors.all(),
    remoteIdentity => remoteIdentity.find(identity => identity.identity_id === identity_id)
  ),
};

const reducer = {
  [actions.get]: state => state,
  [actions.post]: (state, { body }) => ([
    ...state,
    {
      identity_id: uuidv1(),
      ...body,
    }
  ]),
  [actions.createOauth]: (state, { req }) => {
    const { providerName } = req.params;

    switch (providerName) {
      case 'gmail':
        return [
          ...state,
          {
            identity_id: uuidv1(),
            display_name: 'dev@gmail',
            identifier: 'dev@gmail.com',
            infos: {
              authtype:'oauth2',
              inserver:'imap.gmail.com:993',
              lastseenuid:'',
              lastsync:'',
              outserver:'smtp.gmail.com:465',
              pollinterval:'15',
              provider:'gmail',
              uidvalidity:''
            },
            protocol: 'email',
            status: 'inactive',
            type: 'remote',
          },
        ];
      case 'twitter':
        return [
          ...state,
          {
            identity_id: uuidv1(),
            display_name: '@dev',
            identifier: '@dev',
            infos: {
              authtype:'oauth2',
              lastseenuid:'',
              lastsync:'',
              pollinterval:'15',
              provider:'twitter',
              uidvalidity:''
            },
            protocol: 'twitter',
            status: 'inactive',
            type: 'remote',
          },
        ];
      default:
        throw new Error('unknown provider');
    }
  },
  [actions.patch]: (state, { params, body }) => {
    const nextState = [...state];
    const original = state.find(remoteIdentity => remoteIdentity.identity_id === params.identity_id);
    if (!original) {
      throw `remoteIdentity w/ id ${params.identity_id} not found`;
    }
    const index = nextState.indexOf(original);
    const { current_state, ...props } = body;
    nextState[index] = {
      ...original,
      ...props,
    };

    return nextState;
  },
  [actions.delete]: (state, { params, body }) => {
    const original = state.find(remoteIdentity => remoteIdentity.identity_id === params.identity_id);
    if (!original) {
      throw `remoteIdentity w/ id ${params.identity_id} not found`;
    }

    return [...state.filter(remoteIdentity => remoteIdentity.identity_id !== params.identity_id)];
  },
};

const routes = {
  'GET /': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
    middlewares: [createCollectionMiddleware('remote_identities')],
  },
  'POST /': {
    action: actions.post,
    selector: selectors.lastLocation,
    status: 200,
  },
  'GET /:identity_id': {
    action: actions.get,
    selector: selectors.byId,
    status: 200,
  },
  'PATCH /:identity_id': {
    action: actions.patch,
    status: 204,
  },
  'DELETE /:identity_id': {
    action: actions.delete,
    selector: selectors.byId,
    status: 204,
  },
};

export default {
  name: 'remote_identities',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/identities/remotes',
  routes: routes,
};


================================================
FILE: devtools/api-mock/search/data.json
================================================
{
  "total": 2,
  "messages_hits": {
    "total": 2,
    "messages": [
      {
        "highlights": { "???": ["I like cooking foobar. You, minion. Lift my arm."]},
        "document": {
          "attachments": [],
          "body": "<p>It's okay, Bender. I like cooking too. You, minion. Lift my arm. AFTER H=\r\nIM! I don't know what you did, Fry, but once again, you screwed up! Now all\r\nthe planets are gonna start cracking wise abo",
          "excerpt": "It's okay, Bender. I like cooking too. You, minion. Lift my arm. AFTER HIM! I don't ...",
          "date": "2017-03-21T10:55:00.153000+00:00",
          "date_insert": "2017-03-21T10:55:00.153000+00:00",
          "discussion_id": "cd53e13a-267d-4d9c-97ee-d0fc59c64200",
          "identities": [{
            "display_name": "Jaune",
            "identifier": "john@caliopen.local"
          }],
          "importance_level": 0,
          "is_answered": false,
          "is_draft": false,
          "message_id": "11111111-267d-4d9c-97ee-d0fc59c64201",
          "participants": [{
            "address": "test@caliopen.local",
            "contact_ids": ["1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
            "label": "foo",
            "protocol": "email",
            "type": "To"
          }, {
            "address": "john@caliopen.local",
            "contact_ids": ["1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
            "label": "Jaune john",
            "protocol": "email",
            "type": "Cc"
          }, {
            "address": "zoidberg@planet-express.tld",
            "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42f07e0"],
            "label": "zoidberg",
            "protocol": "email",
            "type": "From"
          }],
          "privacy_features": {},
          "raw_msg_id": "aaaaaaaa-267d-4d9c-97ee-d0fc59c64201",
          "subject": "It's okay, Bender. I like cooking too",
          "tags": ["robot", "IMPORTANT"],
          "type": "email",
          "pi": { "technic": 50, "context": 45, "comportment": 25, "version": 1 },
          "user_id": ""
        }
      },
      {
        "highlights": { "???": ["He's Foobar too powerful! Can I use the gun? "]},
        "document": {
          "attachments": [],
          "body": "Fry! Stay back! He's too powerful! Can I use the gun? I barely knew Philip, but as a clergyman I have no problem telling his most intimate friends all about him. What are you hacking off? Is it my torso?! 'It is!' My precious torso!",
          "excerpt": "Fry! Stay back! He's too powerful! Can I use the gun? I barely knew Philip, but as a ...",
          "date": "2017-03-21T12:55:00.153000+00:00",
          "date_insert": "2017-03-21T12:55:00.153000+00:00",
          "discussion_id": "cd53e13a-267d-4d9c-97ee-d0fc59c64200",
          "identities": [{
            "display_name": "Jaune",
            "identifier": "john@caliopen.local"
          }],
          "importance_level": 0,
          "is_answered": false,
          "is_draft": false,
          "message_id": "11111111-267d-4d9c-97ee-d0fc59c64202",
          "participants": [{
            "address": "test@caliopen.local",
            "contact_ids": ["1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
            "label": "foo",
            "protocol": "email",
            "type": "Cc"
          }, {
            "address": "john@caliopen.local",
            "contact_ids": ["1039cdcc-1f6f-4b5d-9c8a-5d7c711f357f"],
            "label": "Jaune john",
            "protocol": "email",
            "type": "From"
          }, {
            "address": "zoidberg@planet-express.tld",
            "contact_ids": ["0ba2e346-e4f8-4c45-9adc-eeb1d42f07e0"],
            "label": "zoidberg",
            "protocol": "email",
            "type": "To"
          }],
          "privacy_features": {},
          "raw_msg_id": "aaaaaaaa-267d-4d9c-97ee-d0fc59c64202",
          "tags": ["robot", "INBOX"],
          "type": "email",
          "pi": { "technic": 30, "context": 25, "comportment": 25, "version": 1 },
          "user_id": ""
        }
      }
    ]
  },
  "contact_hits": {
    "total": 0,
    "contacts": []
  }
}


================================================
FILE: devtools/api-mock/search/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

const actions = {
};

const match = ({ item, props, searchTerms }) => props.find(propName =>
      item[propName] && item[propName].toLowerCase().includes(searchTerms.toLowerCase()));

const selectors = {
  all: () => state => state.search,
};

const reducer = {
};

const routes = {
  'GET /': {
    selector: selectors.all,
    status: 200,
  },
};

export default {
  name: 'search',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/search',
  routes: routes,
};


================================================
FILE: devtools/api-mock/settings/data.json
================================================
{
  "default_locale": "en-US",
  "message_display_format": "rich_text",
  "contact_display_format": "given_name, family_name",
  "contact_display_order": "given_name",
  "notification_enabled": true,
  "notification_message_preview": "always",
  "notification_sound_enabled": true,
  "notification_delay_disappear": 10
}


================================================
FILE: devtools/api-mock/settings/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

const actions = {
  get: createAction('Get settings'),
  patch: createAction('Patch settings'),
};

const selectors = {
  all: () => state => state.settings,
};

const reducer = {
  [actions.patch]: (state, { params, body }) => {
    const { current_state, ...props } = body;

    return  {
      ...state,
      ...props,
    };
  },
};

const routes = {
  'GET': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
  },
  'PATCH': {
    action: actions.patch,
    status: 204,
  },
};

export default {
  name: 'settings',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v1/settings',
  routes: routes,
};


================================================
FILE: devtools/api-mock/tags/data.json
================================================
[
  {
    "name": "INBOX",
    "type": "system"
  },
  {
    "name": "IMPORTANT",
    "type": "system"
  },
  {
    "name": "SPAM",
    "type": "system"
  },
  {
    "name": "foobar",
    "label": "Foobar",
    "type": "user"
  },
  {
    "name": "planet-express",
    "label": "Planet Express",
    "type": "user"
  },
  {
    "name": "humans",
    "label": "Humans",
    "type": "user"
  },
  {
    "name": "aliens",
    "label": "Aliens",
    "type": "user"
  },
  {
    "name": "amphibians",
    "label": "Amphibians",
    "type": "user"
  },
  {
    "name": "robot",
    "label": "Robot",
    "type": "user"
  }
]


================================================
FILE: devtools/api-mock/tags/index.js
================================================
import { createAction, createSelector } from 'bouchon';
import { v1 as uuidv1 } from 'uuid';
import createCollectionMiddleware from '../collection-middleware';

const actions = {
  get: createAction('Get tags'),
  post: createAction('Create tag'),
  delete: createAction('Delete a tag'),
  patch: createAction('Patch a tag'),
};

const selectors = {
  all: () => state => state.tags,
  last: () => state => [...state.tags].pop(),
  byName: ({ name }) => createSelector(
    selectors.all(),
    tags => tags.find(tag => tag.name === name)
  ),
  location: () => createSelector(
    selectors.last(),
    tag => ({ location: `/api/v2/tags/${tag.name}` })
  ),
};

const reducer = {
  [actions.get]: state => state,
  [actions.post]: (state, { body, res }) => {
    const name = body.name || body.label.replace(' ', '-').toLowerCase();
    const exists = state.some(tag => tag.name === name);

    if (exists) {
      res.status(409).send({
        errors: [{ message: 'Tag already exist', code: 422, name: 'uniqueness' }],
      });

      return state;
    }

    return [
      ...state,
      { ...body, type: 'user', label: body.label || name, name },
    ];
  },
  [actions.delete]: (state, { params }) => {
    const copy = state.slice(0);
    return [...state].filter(tag => tag.name !== params.name);
  },
  [actions.patch]: (state, { params, body }) => {
    const nextState = [...state];
    const original = state.find(tag => tag.name === params.name);
    if (!original) {
      throw `tag w/ id ${params.name} not found`;
    }
    const index = nextState.indexOf(original);
    const { current_state, ...props } = body;
    nextState[index] = {
      ...original,
      ...props,
    };

    return nextState;
  },
};

const routes = {
  'GET /': {
    action: actions.get,
    selector: selectors.all,
    status: 200,
    middlewares: [createCollectionMiddleware('tags')],
  },
  'POST /': {
    action: actions.post,
    selector: selectors.location,
    status: 200,
  },
  'GET /:name': {
    action: actions.get,
    selector: selectors.byName,
    status: 200,
  },
  'DELETE /:name': {
    action: actions.delete,
    status: 204,
  },
  'PATCH /:name': {
    action: actions.patch,
    status: 204,
  },
};

export default {
  name: 'tags',
  data: require('./data.json'),
  reducer: reducer,
  endpoint: '/api/v2/tags',
  routes: routes,
};


================================================
FILE: devtools/clean-dev-storage.sh
================================================
#!/bin/bash
#
# DEVELOPMENT ONLY SCRIPT
#
# Clean docker containers and volumes where data are stored

docker-compose kill cassandra elasticsearch object_store
docker-compose rm -f cassandra elasticsearch object_store
docker volume rm devtools_db devtools_index devtools_store

================================================
FILE: devtools/conf/proxy-api.conf
================================================

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
    upstream apiv1 {
        least_conn;
        server apiv1:6543;
    }

    upstream apiv2 {
        least_conn;
        server apiv2:6544;
    }

    server {
        listen    31415;
        listen    [::]:31415;
        server_name api;

        client_max_body_size 5m;

        location /api/v1 {
                proxy_pass http://apiv1;
        }

        location /api/v2 {
                proxy_pass  http://apiv2;
        }
    }
}



================================================
FILE: devtools/docker-compose.staging.yml
================================================
version: '2.1'
volumes:
  index:
    driver: local
  db:
    driver: local
  store:
    driver: local
services:
  # Proxy API
  proxyapi:
    image: nginx
    depends_on:
      - apiv1
      - apiv2
    expose:
      - "31415"
    volumes:
      - ./conf/proxy-api.conf:/etc/nginx/nginx.conf
  # Caliopen APIv2
  apiv2:
    image: public-registry.caliopen.org/caliopen_apiv2:develop
    depends_on:
      - redis
      - cassandra
      - nats
      - elasticsearch
      - objectstore
    expose:
      - "6544"
    volumes:
      - ../src/backend/configs/apiv2.yaml:/etc/caliopen/apiv2.yaml
      - ../src/backend/configs/swagger.json:/etc/caliopen/swagger.json

  # Caliopen APIv1
  apiv1:
    image: public-registry.caliopen.org/caliopen_apiv1:develop
    depends_on:
      - redis
      - cassandra
      - elasticsearch
    expose:
      - "6543"
    volumes:
      - ../src/backend/configs/apiv1.ini:/etc/caliopen/apiv1.ini
      - ../src/backend/configs/caliopen.yaml:/etc/caliopen/caliopen.yaml
      - ../src/backend/configs/swagger.json:/etc/caliopen/swagger.json

  # ### Redis Database
  #
  # Used to store sessions.
  redis:
    image: redis
    expose:
      - "6379"

  # ### Cassandra
  #
  # Cassandra is used as the reference storage for business data
  cassandra:
    image: scylladb/scylla
    expose:
      - "9042"
      - "9160"
      - "7000"
    volumes:
      - db:/var/lib/scylla
    entrypoint:
      - /docker-entrypoint.py
      - --memory
      - 512M

  # ### Elasticsearch
  #
  # Used to index mail content and ensure great research performances.
  elasticsearch:
    image: elasticsearch:5-alpine
    expose:
      - "9200"
    environment:
      - xpack.security.enabled=false
      - xpack.monitoring.enabled=false
      - "ES_JAVA_OPTS=-Xms512M -Xmx512M"
    volumes:
      - index:/usr/share/elasticsearch/data

  # Caliopen cli tool
  cli:
    image: public-registry.caliopen.org/caliopen_cli:develop
    depends_on:
      - cassandra
      - elasticsearch
      - lmtpd
    environment:
      CQLENG_ALLOW_SCHEMA_MANAGEMENT: 1
    volumes:
      - .:/srv/caliopen/src/backend/devtools
      - ../src/backend/configs/caliopen.yaml:/etc/caliopen/caliopen.yaml

  # Caliopen frontend
  frontend:
    image: public-registry.caliopen.org/caliopen_frontend:develop
    depends_on:
      - proxyapi
    ports:
      - "127.0.0.1:4000:4000"
    environment:
      CALIOPEN_API_HOSTNAME: proxyapi

  # Broker
  lmtpd:
    image: public-registry.caliopen.org/caliopen_lmtpd:develop
    depends_on:
      - cassandra
      - elasticsearch
      - objectstore
      - nats
      - mqworker
    ports:
      - "127.0.0.1:2525:2525"
    volumes:
      - ../src/backend/configs/lmtp.yaml:/etc/caliopen/lmtp.yaml

  # NATS
  nats:
    image: nats:1.4.0
    expose:
      - "4222"

  # NATS Message Handler
  mqworker:
    image: public-registry.caliopen.org/caliopen_mq_worker:develop
    depends_on:
      - cassandra
      - elasticsearch
      - nats
    volumes:
      - ../src/backend/configs/caliopen.yaml:/etc/caliopen/caliopen.yaml

  # object storage
  objectstore:
    image: minio/minio:latest
    expose:
      - "9090"
    volumes:
      - ../src/backend/configs/minio:/etc/caliopen/minio
      - store:/export
    command:
      server --address :9090 -C /etc/caliopen/minio /export
    environment:
      - MINIO_ACCESS_KEY=CALIOPEN_ACCESS_KEY_
      - MINIO_SECRET_KEY=CALIOPEN_SECRET_KEY_BE_GOOD_AND_LIVE_OLD

  # Worker for remote identities
  imapworker:
    image: public-registry.caliopen.org/caliopen_imap_worker:develop
    depends_on:
      - cassandra
      - objectstore
      - elasticsearch
      - nats
    volumes:
      - ../src/backend/configs/imapworker.yaml:/etc/caliopen/imapworker.yaml
    environment:
      - MINIO_ACCESS_KEY=CALIOPEN_ACCESS_KEY_
      - MINIO_SECRET_KEY=CALIOPEN_SECRET_KEY_BE_GOOD_AND_LIVE_OLD

  twitterworker:
    image: public-registry.caliopen.org/caliopen_twitter_worker:develop
    depends_on:
    - cassandra
    - objectstore
    - elasticsearch
    - nats
    volumes:
    - ../src/backend/configs/twitterworker.yaml:/etc/caliopen/twitterworker.yaml

  # Poller for remote identities
  identitypoller:
    image: public-registry.caliopen.org/caliopen_identity_poller:develop
    depends_on:
      - imapworker
      - twitterworker
      - cassandra
      - nats
    volumes:
      - ../src/backend/configs/idpoller.yaml:/etc/caliopen/idpoller.yaml


  # Postfix : a complete smpt server that act as the Caliopen's MTA
  # TODO


================================================
FILE: devtools/docker-compose.yml
================================================
version: '2.1'
volumes:
  index:
    driver: local
  db:
    driver: local
  store:
    driver: local

services:
Download .txt
gitextract_it3wvh4t/

├── .drone.yml
├── .git-crypt/
│   ├── .gitattributes
│   └── keys/
│       └── default/
│           └── 0/
│               ├── 3A1172187EF7406FCBCECFA60E68C4F85D04D8FC.gpg
│               ├── A08EA82ED095FCD8575AB3742DC613553716A878.gpg
│               ├── E6711893CE02FDEEA5B1F79FF3D83146E5111526.gpg
│               └── EA440246DFB690B5B1FB4032CE011C4615DB040A.gpg
├── .gitattributes
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── devtools/
│   ├── ES_queries/
│   │   └── Recipient_suggest.json
│   ├── Vagrantfile
│   ├── api-mock/
│   │   ├── README.md
│   │   ├── all.fixture.js
│   │   ├── authentications/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── bin/
│   │   │   └── start
│   │   ├── collection-middleware/
│   │   │   └── index.js
│   │   ├── contacts/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── devices/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── discussions/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── local_identities/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── me/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── messages/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── notifications/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── oauth-mock/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── package.json
│   │   ├── participants/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── providers/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── remote_identities/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── search/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   ├── settings/
│   │   │   ├── data.json
│   │   │   └── index.js
│   │   └── tags/
│   │       ├── data.json
│   │       └── index.js
│   ├── clean-dev-storage.sh
│   ├── conf/
│   │   └── proxy-api.conf
│   ├── docker-compose.staging.yml
│   ├── docker-compose.yml
│   ├── drone/
│   │   ├── build_images.sh
│   │   ├── files_changed.sh
│   │   ├── get_go_dependencies.sh
│   │   ├── get_py_dependencies.sh
│   │   ├── test_front.sh
│   │   ├── test_go.sh
│   │   └── test_py.sh
│   ├── extract/
│   │   └── email_graph.py
│   ├── fixtures/
│   │   ├── mbox/
│   │   │   ├── dev@caliopen.local/
│   │   │   │   ├── 1460463561.5266_1.argentina:2,
│   │   │   │   ├── 1460463561.5266_11.argentina:2,
│   │   │   │   ├── 1460463561.5266_13.argentina:2,
│   │   │   │   ├── 1460463561.5266_15.argentina:2,
│   │   │   │   ├── 1460463561.5266_17.argentina:2,
│   │   │   │   ├── 1460463561.5266_19.argentina:2,
│   │   │   │   ├── 1460463561.5266_21.argentina:2,
│   │   │   │   ├── 1460463561.5266_23.argentina:2,
│   │   │   │   ├── 1460463561.5266_25.argentina:2,
│   │   │   │   ├── 1460463561.5266_27.argentina:2,
│   │   │   │   ├── 1460463561.5266_29.argentina:2,
│   │   │   │   ├── 1460463561.5266_3.argentina:2,
│   │   │   │   ├── 1460463561.5266_31.argentina:2,
│   │   │   │   ├── 1460463561.5266_33.argentina:2,
│   │   │   │   ├── 1460463561.5266_35.argentina:2,
│   │   │   │   ├── 1460463561.5266_37.argentina:2,
│   │   │   │   ├── 1460463561.5266_39.argentina:2,
│   │   │   │   ├── 1460463561.5266_41.argentina:2,
│   │   │   │   ├── 1460463561.5266_43.argentina:2,
│   │   │   │   ├── 1460463561.5266_45.argentina:2,
│   │   │   │   ├── 1460463561.5266_47.argentina:2,
│   │   │   │   ├── 1460463561.5266_49.argentina:2,
│   │   │   │   ├── 1460463561.5266_5.argentina:2,
│   │   │   │   ├── 1460463561.5266_51.argentina:2,
│   │   │   │   ├── 1460463561.5266_53.argentina:2,
│   │   │   │   ├── 1460463561.5266_55.argentina:2,
│   │   │   │   ├── 1460463561.5266_57.argentina:2,
│   │   │   │   ├── 1460463561.5266_59.argentina:2,
│   │   │   │   ├── 1460463561.5266_61.argentina:2,
│   │   │   │   ├── 1460463561.5266_63.argentina:2,
│   │   │   │   ├── 1460463561.5266_7.argentina:2,
│   │   │   │   ├── 1460463561.5266_9.argentina:2,
│   │   │   │   ├── 1460463562.5266_101.argentina:2,
│   │   │   │   ├── 1460463562.5266_103.argentina:2,
│   │   │   │   ├── 1460463562.5266_105.argentina:2,
│   │   │   │   ├── 1460463562.5266_107.argentina:2,
│   │   │   │   ├── 1460463562.5266_109.argentina:2,
│   │   │   │   ├── 1460463562.5266_111.argentina:2,
│   │   │   │   ├── 1460463562.5266_113.argentina:2,
│   │   │   │   ├── 1460463562.5266_115.argentina:2,
│   │   │   │   ├── 1460463562.5266_117.argentina:2,
│   │   │   │   ├── 1460463562.5266_119.argentina:2,
│   │   │   │   ├── 1460463562.5266_121.argentina:2,
│   │   │   │   ├── 1460463562.5266_123.argentina:2,
│   │   │   │   ├── 1460463562.5266_125.argentina:2,
│   │   │   │   ├── 1460463562.5266_127.argentina:2,
│   │   │   │   ├── 1460463562.5266_129.argentina:2,
│   │   │   │   ├── 1460463562.5266_131.argentina:2,
│   │   │   │   ├── 1460463562.5266_133.argentina:2,
│   │   │   │   ├── 1460463562.5266_135.argentina:2,
│   │   │   │   ├── 1460463562.5266_137.argentina:2,
│   │   │   │   ├── 1460463562.5266_139.argentina:2,
│   │   │   │   ├── 1460463562.5266_141.argentina:2,
│   │   │   │   ├── 1460463562.5266_143.argentina:2,
│   │   │   │   ├── 1460463562.5266_145.argentina:2,
│   │   │   │   ├── 1460463562.5266_147.argentina:2,
│   │   │   │   ├── 1460463562.5266_149.argentina:2,
│   │   │   │   ├── 1460463562.5266_151.argentina:2,
│   │   │   │   ├── 1460463562.5266_153.argentina:2,
│   │   │   │   ├── 1460463562.5266_65.argentina:2,
│   │   │   │   ├── 1460463562.5266_67.argentina:2,
│   │   │   │   ├── 1460463562.5266_69.argentina:2,
│   │   │   │   ├── 1460463562.5266_71.argentina:2,
│   │   │   │   ├── 1460463562.5266_73.argentina:2,
│   │   │   │   ├── 1460463562.5266_75.argentina:2,
│   │   │   │   ├── 1460463562.5266_77.argentina:2,
│   │   │   │   ├── 1460463562.5266_79.argentina:2,
│   │   │   │   ├── 1460463562.5266_81.argentina:2,
│   │   │   │   ├── 1460463562.5266_83.argentina:2,
│   │   │   │   ├── 1460463562.5266_85.argentina:2,
│   │   │   │   ├── 1460463562.5266_87.argentina:2,
│   │   │   │   ├── 1460463562.5266_89.argentina:2,
│   │   │   │   ├── 1460463562.5266_91.argentina:2,
│   │   │   │   ├── 1460463562.5266_93.argentina:2,
│   │   │   │   ├── 1460463562.5266_95.argentina:2,
│   │   │   │   ├── 1460463562.5266_97.argentina:2,
│   │   │   │   ├── 1460463562.5266_99.argentina:2,
│   │   │   │   ├── 1460463563.5266_155.argentina:2,
│   │   │   │   ├── 1460463563.5266_157.argentina:2,
│   │   │   │   ├── 1460463563.5266_159.argentina:2,
│   │   │   │   ├── 1460463563.5266_161.argentina:2,
│   │   │   │   ├── 1460463563.5266_163.argentina:2,
│   │   │   │   ├── 1460463563.5266_165.argentina:2,
│   │   │   │   ├── 1460463563.5266_167.argentina:2,
│   │   │   │   ├── 1460463563.5266_169.argentina:2,
│   │   │   │   ├── 1460463563.5266_171.argentina:2,
│   │   │   │   ├── 1460463563.5266_173.argentina:2,
│   │   │   │   ├── 1460463563.5266_175.argentina:2,
│   │   │   │   ├── 1460463563.5266_177.argentina:2,
│   │   │   │   ├── 1460463563.5266_179.argentina:2,
│   │   │   │   ├── 1460463563.5266_181.argentina:2,
│   │   │   │   ├── 1460463563.5266_183.argentina:2,
│   │   │   │   ├── 1460463563.5266_185.argentina:2,
│   │   │   │   ├── 1460463563.5266_187.argentina:2,
│   │   │   │   ├── 1460463563.5266_189.argentina:2,
│   │   │   │   ├── 1460463563.5266_193.argentina:2,
│   │   │   │   ├── 1460463563.5266_195.argentina:2,
│   │   │   │   ├── 1460463563.5266_197.argentina:2,
│   │   │   │   ├── 1460463563.5266_199.argentina:2,
│   │   │   │   ├── 1460463563.5266_201.argentina:2,
│   │   │   │   ├── 1460463563.5266_205.argentina:2,
│   │   │   │   ├── 1460463563.5266_207.argentina:2,
│   │   │   │   ├── 1460463563.5266_209.argentina:2,
│   │   │   │   ├── 1460463563.5266_211.argentina:2,
│   │   │   │   ├── 1460463563.5266_213.argentina:2,
│   │   │   │   ├── 1460463563.5266_215.argentina:2,
│   │   │   │   ├── 1460463563.5266_217.argentina:2,
│   │   │   │   ├── 1460463563.5266_219.argentina:2,
│   │   │   │   ├── 1460463563.5266_221.argentina:2,
│   │   │   │   ├── 1460463563.5266_223.argentina:2,
│   │   │   │   ├── 1460463563.5266_225.argentina:2,
│   │   │   │   ├── 1460463563.5266_227.argentina:2,
│   │   │   │   ├── 1460463563.5266_229.argentina:2,
│   │   │   │   ├── 1460463563.5266_231.argentina:2,
│   │   │   │   ├── 1460463563.5266_233.argentina:2,
│   │   │   │   ├── 1460463563.5266_235.argentina:2,
│   │   │   │   ├── 1460463563.5266_237.argentina:2,
│   │   │   │   ├── 1460463563.5266_239.argentina:2,
│   │   │   │   ├── 1460463563.5266_241.argentina:2,
│   │   │   │   ├── 1460463563.5266_243.argentina:2,
│   │   │   │   ├── 1460463564.5266_245.argentina:2,
│   │   │   │   ├── 1460463564.5266_247.argentina:2,
│   │   │   │   ├── 1460463564.5266_249.argentina:2,
│   │   │   │   ├── 1460463564.5266_253.argentina:2,
│   │   │   │   ├── 1460463564.5266_255.argentina:2,
│   │   │   │   ├── 1460463564.5266_257.argentina:2,
│   │   │   │   ├── 1460463564.5266_259.argentina:2,
│   │   │   │   ├── 1460463564.5266_261.argentina:2,
│   │   │   │   ├── 1460463564.5266_263.argentina:2,
│   │   │   │   ├── 1460463564.5266_265.argentina:2,
│   │   │   │   ├── 1460463564.5266_267.argentina:2,
│   │   │   │   ├── 1460463564.5266_269.argentina:2,
│   │   │   │   ├── 1460463564.5266_271.argentina:2,
│   │   │   │   ├── 1460463564.5266_273.argentina:2,
│   │   │   │   ├── 1460463564.5266_275.argentina:2,
│   │   │   │   ├── 1460463564.5266_277.argentina:2,
│   │   │   │   ├── 1460463564.5266_279.argentina:2,
│   │   │   │   ├── 1460463564.5266_281.argentina:2,
│   │   │   │   ├── 1460463564.5266_283.argentina:2,
│   │   │   │   ├── 1460463564.5266_285.argentina:2,
│   │   │   │   ├── 1460463564.5266_287.argentina:2,
│   │   │   │   ├── 1460463564.5266_289.argentina:2,
│   │   │   │   ├── 1460463564.5266_291.argentina:2,
│   │   │   │   ├── 1460463564.5266_293.argentina:2,
│   │   │   │   ├── 1460463564.5266_295.argentina:2,
│   │   │   │   ├── 1460463564.5266_297.argentina:2,
│   │   │   │   ├── 1460463564.5266_299.argentina:2,
│   │   │   │   ├── 1460463564.5266_301.argentina:2,
│   │   │   │   ├── 1460463564.5266_303.argentina:2,
│   │   │   │   ├── 1460463564.5266_305.argentina:2,
│   │   │   │   ├── 1460463564.5266_307.argentina:2,
│   │   │   │   ├── 1460463564.5266_309.argentina:2,
│   │   │   │   ├── 1460463564.5266_311.argentina:2,
│   │   │   │   ├── 1460463564.5266_313.argentina:2,
│   │   │   │   ├── 1460463564.5266_315.argentina:2,
│   │   │   │   ├── 1460463564.5266_317.argentina:2,
│   │   │   │   ├── 1460463564.5266_319.argentina:2,
│   │   │   │   ├── 1460463564.5266_321.argentina:2,
│   │   │   │   ├── 1460463564.5266_323.argentina:2,
│   │   │   │   ├── 1460463564.5266_325.argentina:2,
│   │   │   │   ├── 1460463564.5266_327.argentina:2,
│   │   │   │   ├── 1460463564.5266_329.argentina:2,
│   │   │   │   ├── 1460463564.5266_331.argentina:2,
│   │   │   │   ├── 1460463564.5266_333.argentina:2,
│   │   │   │   ├── 1460463564.5266_335.argentina:2,
│   │   │   │   ├── 1460463564.5266_337.argentina:2,
│   │   │   │   ├── 1460463564.5266_339.argentina:2,
│   │   │   │   ├── 1460463564.5266_341.argentina:2,
│   │   │   │   ├── 1460463564.5266_343.argentina:2,
│   │   │   │   ├── 1460463565.5266_345.argentina:2,
│   │   │   │   ├── 1460463565.5266_347.argentina:2,
│   │   │   │   ├── 1460463565.5266_349.argentina:2,
│   │   │   │   ├── 1460463565.5266_351.argentina:2,
│   │   │   │   ├── 1460463565.5266_353.argentina:2,
│   │   │   │   ├── 1460463565.5266_355.argentina:2,
│   │   │   │   ├── 1460463565.5266_357.argentina:2,
│   │   │   │   ├── 1460463565.5266_359.argentina:2,
│   │   │   │   ├── 1460463565.5266_361.argentina:2,
│   │   │   │   ├── 1460463565.5266_363.argentina:2,
│   │   │   │   ├── 1460463565.5266_365.argentina:2,
│   │   │   │   ├── 1460463565.5266_367.argentina:2,
│   │   │   │   ├── 1460463565.5266_369.argentina:2,
│   │   │   │   ├── 1460463565.5266_371.argentina:2,
│   │   │   │   ├── 1460463565.5266_373.argentina:2,
│   │   │   │   ├── 1460463565.5266_375.argentina:2,
│   │   │   │   ├── 1460463565.5266_377.argentina:2,
│   │   │   │   ├── 1460463565.5266_379.argentina:2,
│   │   │   │   ├── 1460463565.5266_381.argentina:2,
│   │   │   │   ├── 1460463565.5266_383.argentina:2,
│   │   │   │   ├── 1460463565.5266_385.argentina:2,
│   │   │   │   ├── 1460463565.5266_387.argentina:2,
│   │   │   │   ├── 1460463565.5266_389.argentina:2,
│   │   │   │   ├── 1460463565.5266_391.argentina:2,
│   │   │   │   ├── 1460463565.5266_393.argentina:2,
│   │   │   │   ├── 1460463565.5266_395.argentina:2,
│   │   │   │   ├── 1460463565.5266_397.argentina:2,
│   │   │   │   ├── 1460463565.5266_399.argentina:2,
│   │   │   │   ├── 1460463565.5266_401.argentina:2,
│   │   │   │   ├── 1460463565.5266_403.argentina:2,
│   │   │   │   ├── 1460463565.5266_405.argentina:2,
│   │   │   │   ├── 1460463565.5266_407.argentina:2,
│   │   │   │   ├── 1460463565.5266_409.argentina:2,
│   │   │   │   ├── 1460463565.5266_411.argentina:2,
│   │   │   │   ├── 1460463565.5266_413.argentina:2,
│   │   │   │   ├── 1460463565.5266_415.argentina:2,
│   │   │   │   ├── 1460463565.5266_417.argentina:2,
│   │   │   │   ├── 1460463565.5266_419.argentina:2,
│   │   │   │   ├── 1460463565.5266_421.argentina:2,
│   │   │   │   ├── 1460463565.5266_423.argentina:2,
│   │   │   │   ├── 1460463565.5266_425.argentina:2,
│   │   │   │   ├── 1460463565.5266_427.argentina:2,
│   │   │   │   ├── 1460463565.5266_429.argentina:2,
│   │   │   │   ├── 1460463565.5266_431.argentina:2,
│   │   │   │   ├── 1460463565.5266_433.argentina:2,
│   │   │   │   ├── 1460463565.5266_435.argentina:2,
│   │   │   │   ├── 1460463566.5266_437.argentina:2,
│   │   │   │   ├── 1460463566.5266_439.argentina:2,
│   │   │   │   ├── 1460463566.5266_441.argentina:2,
│   │   │   │   ├── 1460463566.5266_443.argentina:2,
│   │   │   │   ├── 1460463566.5266_445.argentina:2,
│   │   │   │   ├── 1460463566.5266_447.argentina:2,
│   │   │   │   ├── 1460463566.5266_449.argentina:2,
│   │   │   │   ├── 1460463566.5266_451.argentina:2,
│   │   │   │   ├── 1460463566.5266_453.argentina:2,
│   │   │   │   ├── 1460463566.5266_455.argentina:2,
│   │   │   │   ├── 1460463566.5266_457.argentina:2,
│   │   │   │   ├── 1460463566.5266_459.argentina:2,
│   │   │   │   ├── 1460463566.5266_461.argentina:2,
│   │   │   │   ├── 1460463566.5266_463.argentina:2,
│   │   │   │   ├── 1460463566.5266_465.argentina:2,
│   │   │   │   ├── 1460463566.5266_467.argentina:2,
│   │   │   │   ├── 1460463566.5266_469.argentina:2,
│   │   │   │   ├── 1460463566.5266_471.argentina:2,
│   │   │   │   ├── 1460463566.5266_473.argentina:2,
│   │   │   │   ├── 1460463566.5266_475.argentina:2,
│   │   │   │   ├── 1460463567.5266_477.argentina:2,
│   │   │   │   ├── 1460463567.5266_483.argentina:2,
│   │   │   │   ├── 1460463567.5266_485.argentina:2,
│   │   │   │   ├── 1460463567.5266_487.argentina:2,
│   │   │   │   ├── 1460463567.5266_489.argentina:2,
│   │   │   │   ├── 1460463567.5266_491.argentina:2,
│   │   │   │   ├── 1460463567.5266_493.argentina:2,
│   │   │   │   ├── 1460463567.5266_495.argentina:2,
│   │   │   │   ├── 1460463567.5266_497.argentina:2,
│   │   │   │   ├── 1460463567.5266_499.argentina:2,
│   │   │   │   ├── 1460463567.5266_503.argentina:2,
│   │   │   │   ├── 1460463567.5266_505.argentina:2,
│   │   │   │   ├── 1460463567.5266_507.argentina:2,
│   │   │   │   ├── 1460463567.5266_509.argentina:2,
│   │   │   │   ├── 1460463567.5266_511.argentina:2,
│   │   │   │   ├── 1460463567.5266_513.argentina:2,
│   │   │   │   ├── 1460463567.5266_515.argentina:2,
│   │   │   │   ├── 1460463567.5266_517.argentina:2,
│   │   │   │   ├── 1460463567.5266_519.argentina:2,
│   │   │   │   ├── 1460463567.5266_521.argentina:2,
│   │   │   │   ├── 1460463567.5266_525.argentina:2,
│   │   │   │   ├── 1460463567.5266_527.argentina:2,
│   │   │   │   ├── 1460463567.5266_529.argentina:2,
│   │   │   │   ├── 1460463567.5266_531.argentina:2,
│   │   │   │   ├── 1460463568.5266_533.argentina:2,
│   │   │   │   ├── 1460463568.5266_535.argentina:2,
│   │   │   │   ├── 1460463568.5266_537.argentina:2,
│   │   │   │   ├── 1460463568.5266_539.argentina:2,
│   │   │   │   ├── 1460463568.5266_541.argentina:2,
│   │   │   │   ├── 1460463568.5266_543.argentina:2,
│   │   │   │   ├── 1460463568.5266_545.argentina:2,
│   │   │   │   ├── 1460463568.5266_547.argentina:2,
│   │   │   │   ├── 1460463568.5266_549.argentina:2,
│   │   │   │   ├── 1460463568.5266_551.argentina:2,
│   │   │   │   ├── 1460463568.5266_553.argentina:2,
│   │   │   │   ├── 1460463568.5266_555.argentina:2,
│   │   │   │   ├── 1460463568.5266_557.argentina:2,
│   │   │   │   ├── 1460463568.5266_559.argentina:2,
│   │   │   │   ├── 1460463568.5266_561.argentina:2,
│   │   │   │   ├── 1460463568.5266_563.argentina:2,
│   │   │   │   ├── 1460463568.5266_565.argentina:2,
│   │   │   │   ├── 1460463568.5266_567.argentina:2,
│   │   │   │   ├── 1460463568.5266_569.argentina:2,
│   │   │   │   ├── 1460463568.5266_571.argentina:2,
│   │   │   │   ├── 1460463568.5266_573.argentina:2,
│   │   │   │   ├── 1460463568.5266_575.argentina:2,
│   │   │   │   ├── 1460463568.5266_577.argentina:2,
│   │   │   │   ├── 1460463568.5266_579.argentina:2,
│   │   │   │   ├── 1460463568.5266_581.argentina:2,
│   │   │   │   ├── 1460463568.5266_583.argentina:2,
│   │   │   │   ├── 1460463568.5266_585.argentina:2,
│   │   │   │   ├── 1460463568.5266_587.argentina:2,
│   │   │   │   ├── 1460463568.5266_589.argentina:2,
│   │   │   │   ├── 1460463568.5266_591.argentina:2,
│   │   │   │   ├── 1460463568.5266_593.argentina:2,
│   │   │   │   ├── 1460463568.5266_595.argentina:2,
│   │   │   │   ├── 1460463568.5266_597.argentina:2,
│   │   │   │   ├── 1460463568.5266_599.argentina:2,
│   │   │   │   ├── 1460463568.5266_601.argentina:2,
│   │   │   │   ├── 1460463568.5266_603.argentina:2,
│   │   │   │   ├── 1460463568.5266_605.argentina:2,
│   │   │   │   ├── 1460463568.5266_607.argentina:2,
│   │   │   │   ├── 1460463568.5266_609.argentina:2,
│   │   │   │   ├── 1460463568.5266_611.argentina:2,
│   │   │   │   ├── 1460463568.5266_613.argentina:2,
│   │   │   │   ├── 1460463568.5266_615.argentina:2,
│   │   │   │   ├── 1460463568.5266_617.argentina:2,
│   │   │   │   ├── 1460463569.5266_619.argentina:2,
│   │   │   │   ├── 1460463569.5266_621.argentina:2,
│   │   │   │   ├── 1460463569.5266_623.argentina:2,
│   │   │   │   ├── 1460463569.5266_625.argentina:2,
│   │   │   │   ├── 1460463569.5266_627.argentina:2,
│   │   │   │   ├── 1460463569.5266_629.argentina:2,
│   │   │   │   ├── 1460463569.5266_631.argentina:2,
│   │   │   │   ├── 1460463569.5266_633.argentina:2,
│   │   │   │   ├── 1460463569.5266_635.argentina:2,
│   │   │   │   ├── 1460463569.5266_637.argentina:2,
│   │   │   │   ├── 1460463569.5266_639.argentina:2,
│   │   │   │   ├── 1460463569.5266_641.argentina:2,
│   │   │   │   ├── 1460463569.5266_643.argentina:2,
│   │   │   │   ├── 1460463569.5266_645.argentina:2,
│   │   │   │   ├── 1460463569.5266_647.argentina:2,
│   │   │   │   ├── 1460463569.5266_649.argentina:2,
│   │   │   │   ├── 1460463569.5266_651.argentina:2,
│   │   │   │   ├── 1460463569.5266_653.argentina:2,
│   │   │   │   ├── 1460463569.5266_655.argentina:2,
│   │   │   │   ├── 1460463569.5266_657.argentina:2,
│   │   │   │   ├── 1460463569.5266_659.argentina:2,
│   │   │   │   ├── 1460463569.5266_661.argentina:2,
│   │   │   │   ├── 1460463569.5266_663.argentina:2,
│   │   │   │   ├── 1460463569.5266_665.argentina:2,
│   │   │   │   ├── 1460463569.5266_667.argentina:2,
│   │   │   │   ├── 1460463569.5266_669.argentina:2,
│   │   │   │   ├── 1460463569.5266_671.argentina:2,
│   │   │   │   ├── 1460463569.5266_673.argentina:2,
│   │   │   │   ├── 1460463569.5266_675.argentina:2,
│   │   │   │   ├── 1460463569.5266_677.argentina:2,
│   │   │   │   ├── 1460463569.5266_679.argentina:2,
│   │   │   │   ├── 1460463569.5266_681.argentina:2,
│   │   │   │   ├── 1460463569.5266_683.argentina:2,
│   │   │   │   ├── 1460463569.5266_685.argentina:2,
│   │   │   │   ├── 1460463569.5266_687.argentina:2,
│   │   │   │   ├── 1460463569.5266_689.argentina:2,
│   │   │   │   ├── 1460463569.5266_691.argentina:2,
│   │   │   │   ├── 1460463569.5266_693.argentina:2,
│   │   │   │   ├── 1460463569.5266_695.argentina:2,
│   │   │   │   ├── 1460463569.5266_697.argentina:2,
│   │   │   │   ├── 1460463569.5266_699.argentina:2,
│   │   │   │   ├── 1460463569.5266_701.argentina:2,
│   │   │   │   ├── 1460463569.5266_703.argentina:2,
│   │   │   │   ├── 1460463569.5266_705.argentina:2,
│   │   │   │   ├── 1460463570.5266_707.argentina:2,
│   │   │   │   ├── 1460463570.5266_709.argentina:2,
│   │   │   │   ├── 1460463570.5266_711.argentina:2,
│   │   │   │   ├── 1460463570.5266_713.argentina:2,
│   │   │   │   ├── 1460463570.5266_715.argentina:2,
│   │   │   │   ├── 1460463570.5266_717.argentina:2,
│   │   │   │   ├── 1460463570.5266_719.argentina:2,
│   │   │   │   ├── 1460463570.5266_721.argentina:2,
│   │   │   │   ├── 1460463570.5266_723.argentina:2,
│   │   │   │   ├── 1460463570.5266_725.argentina:2,
│   │   │   │   ├── 1460463570.5266_727.argentina:2,
│   │   │   │   ├── 1460463570.5266_729.argentina:2,
│   │   │   │   ├── 1460463570.5266_731.argentina:2,
│   │   │   │   ├── 1460463570.5266_733.argentina:2,
│   │   │   │   ├── 1460463570.5266_735.argentina:2,
│   │   │   │   ├── 1460463570.5266_737.argentina:2,
│   │   │   │   ├── 1460463570.5266_739.argentina:2,
│   │   │   │   ├── 1460463570.5266_741.argentina:2,
│   │   │   │   ├── 1460463570.5266_743.argentina:2,
│   │   │   │   ├── 1460463570.5266_745.argentina:2,
│   │   │   │   ├── 1460463570.5266_747.argentina:2,
│   │   │   │   ├── 1460463570.5266_749.argentina:2,
│   │   │   │   ├── 1460463570.5266_751.argentina:2,
│   │   │   │   ├── 1460463570.5266_753.argentina:2,
│   │   │   │   ├── 1460463570.5266_755.argentina:2,
│   │   │   │   ├── 1460463570.5266_757.argentina:2,
│   │   │   │   ├── 1460463570.5266_759.argentina:2,
│   │   │   │   ├── 1460463570.5266_761.argentina:2,
│   │   │   │   ├── 1460463570.5266_763.argentina:2,
│   │   │   │   ├── 1460463570.5266_765.argentina:2,
│   │   │   │   ├── 1460463570.5266_767.argentina:2,
│   │   │   │   ├── 1460463570.5266_769.argentina:2,
│   │   │   │   ├── 1460463570.5266_771.argentina:2,
│   │   │   │   ├── 1460463570.5266_773.argentina:2,
│   │   │   │   ├── 1460463570.5266_775.argentina:2,
│   │   │   │   ├── 1460463570.5266_777.argentina:2,
│   │   │   │   ├── 1460463570.5266_779.argentina:2,
│   │   │   │   ├── 1460463570.5266_781.argentina:2,
│   │   │   │   ├── 1460463571.5266_783.argentina:2,
│   │   │   │   ├── 1460463571.5266_785.argentina:2,
│   │   │   │   ├── 1460463571.5266_787.argentina:2,
│   │   │   │   ├── 1460463571.5266_789.argentina:2,
│   │   │   │   ├── 1460463571.5266_791.argentina:2,
│   │   │   │   ├── 1460463571.5266_793.argentina:2,
│   │   │   │   ├── 1460463571.5266_795.argentina:2,
│   │   │   │   ├── 1460463571.5266_797.argentina:2,
│   │   │   │   ├── 1460463571.5266_799.argentina:2,
│   │   │   │   ├── 1460463571.5266_801.argentina:2,
│   │   │   │   ├── Re: [Caliopdev] CR réunion du 12_12_2014 - David Epely <dey@protonmail.ch> - 2014-12-13 1352.eml
│   │   │   │   ├── Re: [Caliopdev] Compte rendu reunion 21 Novembre - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-22 1046.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re:  matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-26 1605.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re:  matrice de choix framework JS - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-26 2346.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re:  matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-28 1701.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alban Crommer <alban@albancrommer.com> - 2014-11-27 1007.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alban Crommer <alban@albancrommer.com> - 2014-11-28 1625.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alexis <alexis@gandi.net> - 2014-11-28 1518.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Alexis <alexis@gandi.net> - 2014-11-28 1748.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-28 1112.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-28 1724.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-11-27 0132.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - Vincent MINEAUD <vincent@gandi.net> - 2014-11-28 1600.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - joseph@cozycloud.cc - 2014-11-27 1120.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - joseph@cozycloud.cc - 2014-11-27 1228.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-27 1211.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-27 2140.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-28 1222.eml
│   │   │   │   ├── Re: [Caliopdev] Fwd: Re: matrice de choix framework JS - julien muetton <julien.muetton@gandi.net> - 2014-11-28 1609.eml
│   │   │   │   ├── Re: [Caliopdev] Nouveau screencast (brut) - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-30 1724.eml
│   │   │   │   ├── Re: [Caliopdev] Nouveau screencast (brut) - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-01 1214.eml
│   │   │   │   ├── Re: [Caliopdev] Nouveau screencast (brut) - Thomas Laurent <thomas.laurent@gandi.net> - 2014-12-01 1149.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Aymeric Barantal <mric@chamal.fr> - 2014-12-02 1510.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - David Epely <dey@protonmail.ch> - 2014-12-02 1056.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-01 2345.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-02 2319.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-02 2322.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-02 0610.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-02 1158.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaine réunion - julien muetton <julien.muetton@gandi.net> - 2014-12-02 1031.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaines réunions. - Alban Crommer <alban@albancrommer.com> - 2014-12-29 1917.eml
│   │   │   │   ├── Re: [Caliopdev] Prochaines étapes ? - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-06 2135.eml
│   │   │   │   ├── Re: [Caliopdev] [svetlana.meyer@ensc.fr: Bravo!] - Alexis <alexis@gandi.net> - 2014-11-26 1446.eml
│   │   │   │   ├── Re: [Caliopdev] framework js - David Epely <dey@protonmail.ch> - 2014-11-21 0920.eml
│   │   │   │   ├── Re: [Caliopdev] framework js - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-11-21 0059.eml
│   │   │   │   ├── [Caliopdev] CR réunion du 12_12_2014 - Thomas Laurent <thomas.laurent@gandi.net> - 2014-12-12 1701.eml
│   │   │   │   ├── [Caliopdev] Compte rendu reunion 21 Novembre - Aymeric Barantal <mric@chamal.fr> - 2014-11-21 1221.eml
│   │   │   │   ├── [Caliopdev] Fwd: Re:  matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-25 1119.eml
│   │   │   │   ├── [Caliopdev] Nouveau screencast (brut) - Aymeric Barantal <mric@chamal.fr> - 2014-11-28 1718.eml
│   │   │   │   ├── [Caliopdev] Prochaine réunion - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-01 2142.eml
│   │   │   │   ├── [Caliopdev] Prochaines réunions. - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-29 1807.eml
│   │   │   │   ├── [Caliopdev] Prochaines étapes ? - Kajan Sivaramalingam <kajan@kajansiva.com> - 2014-12-06 2108.eml
│   │   │   │   ├── [Caliopdev] [Coin-coin@canapin.com: Petites fautes dans la FAQ] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-24 1840.eml
│   │   │   │   ├── [Caliopdev] [benjamin@sonntag.fr: Fwd: ***UNCHECKED*** Caliopen FAQ] - Laurent Chemla <laurent@brainstorm.fr> - 2014-12-15 1825.eml
│   │   │   │   ├── [Caliopdev] [contact+caliopen@etiennesamson.com: Intégration] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-24 1840.eml
│   │   │   │   ├── [Caliopdev] [groupeiw@gmail.com: Contacter l'équipe CaliOpen] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-25 1810.eml
│   │   │   │   ├── [Caliopdev] [svetlana.meyer@ensc.fr: Bravo!] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-26 1244.eml
│   │   │   │   ├── [Caliopdev] [svetlana.meyer@ensc.fr: Re: Bravo!] - Laurent Chemla <laurent@brainstorm.fr> - 2014-11-26 1246.eml
│   │   │   │   └── [Caliopdev] matrice de choix framework JS - Aymeric Barantal <mric@chamal.fr> - 2014-11-24 1146.eml
│   │   │   └── test@caliopen.local/
│   │   │       ├── test_1.eml
│   │   │       ├── test_2.eml
│   │   │       └── test_3.eml
│   │   ├── messages_body/
│   │   │   ├── flat-html-body
│   │   │   ├── html-mailinglist
│   │   │   ├── html-with-inline-styles
│   │   │   └── spam-htmj-and-styles
│   │   ├── raw_emails/
│   │   │   ├── email-with-iso-8859-1-encoding
│   │   │   ├── html-in-plain-body
│   │   │   ├── html-with-inlined-image
│   │   │   ├── invalid-utf-8
│   │   │   ├── multipart-html
│   │   │   ├── multipart-signed
│   │   │   ├── multipart-with-attachment
│   │   │   ├── sample-mail.eml.txt
│   │   │   ├── signed-and-encrypted
│   │   │   ├── simple
│   │   │   ├── spam-multipart
│   │   │   ├── with-docx-attachment
│   │   │   └── with-json-attachment
│   │   ├── raw_inbound_msg.cql
│   │   ├── twitter/
│   │   │   ├── dm-multimedia.json
│   │   │   └── dm.json
│   │   └── vcard/
│   │       ├── multi.vcf
│   │       ├── rfc2425-1.vcard
│   │       ├── rfc2425-2.vcard
│   │       ├── rfc2425-3.vcard
│   │       ├── rfc2426-1.vcard
│   │       ├── rfc2426-2.vcard
│   │       ├── rfc2426-3.vcard
│   │       ├── rfc2426-4.vcard
│   │       └── rfc2426-5.vcard
│   ├── gen-swagger-spec.sh
│   ├── init.sh
│   ├── kubernetes/
│   │   ├── README.md
│   │   ├── clean-minikube.sh
│   │   ├── configs/
│   │   │   └── dns-config.yaml
│   │   ├── deploy-minikube.sh
│   │   ├── deployments/
│   │   │   ├── apiv1-deployment.yaml
│   │   │   ├── apiv2-deployment.yaml
│   │   │   ├── cassandra-deployment.yaml
│   │   │   ├── elasticsearch-deployment.yaml
│   │   │   ├── frontend-deployment.yaml
│   │   │   ├── identity-poller-deployment.yaml
│   │   │   ├── imap-worker-deployment.yaml
│   │   │   ├── lmtpd-deployment.yaml
│   │   │   ├── message-handler-deployment.yaml
│   │   │   ├── minio-deployment.yaml
│   │   │   ├── nats-deployment.yaml
│   │   │   ├── redis-deployment.yaml
│   │   │   └── smtp-deployment.yaml
│   │   ├── jobs/
│   │   │   ├── cli-admin-creation.yaml
│   │   │   ├── cli-dev-creation.yaml
│   │   │   ├── cli-mail-import.yaml
│   │   │   └── cli-setup.yaml
│   │   ├── services/
│   │   │   ├── apiv1-service.yaml
│   │   │   ├── apiv2-service.yaml
│   │   │   ├── cassandra-service.yaml
│   │   │   ├── elasticsearch-service.yaml
│   │   │   ├── external-go-service.yaml
│   │   │   ├── external-python-service.yaml
│   │   │   ├── frontend-service.yaml
│   │   │   ├── lmtpd-service.yaml
│   │   │   ├── minio-service.yaml
│   │   │   ├── nats-service.yaml
│   │   │   ├── redis-service.yaml
│   │   │   └── smtp-service.yaml
│   │   └── volumeclaims/
│   │       ├── db-persistentvolumeclaim.yaml
│   │       ├── index-persistentvolumeclaim.yaml
│   │       └── store-persistentvolumeclaim.yaml
│   ├── make_release
│   ├── makefile
│   ├── manage_package
│   ├── manage_package-requirements.txt
│   ├── migrations/
│   │   ├── ES_mappings_v2.json
│   │   ├── add_delivered_column_to_raw-message_table.cql
│   │   ├── add_temp_id_to_attachment_type.cql
│   │   ├── fill_message_is_received.py
│   │   ├── index_migration_v0_to_v2.py
│   │   ├── index_migration_v2_to_v3.py
│   │   ├── index_migration_v3_to_v4.py
│   │   ├── index_migration_v4_to_v5.py
│   │   ├── index_migration_v5_to_v6.py
│   │   ├── set_date_sort_in_db.py
│   │   └── update_ecdsa_key.py
│   ├── packages.yaml
│   ├── publish-images.sh
│   ├── registry.conf.template
│   ├── run-tests.sh
│   ├── setup-virtualenv.sh
│   ├── start.sh
│   ├── stop.sh
│   └── storybook/
│       ├── .storybook/
│       │   ├── addons.js
│       │   ├── config.js
│       │   └── webpack.config.js
│       ├── README.md
│       ├── package.json
│       └── stories/
│           ├── CHANGELOG.md
│           ├── Changelog.jsx
│           ├── Guideline/
│           │   ├── index.jsx
│           │   └── style.scss
│           ├── Welcome.jsx
│           ├── components/
│           │   ├── BlockList.jsx
│           │   ├── CollectionFieldGroup.jsx
│           │   ├── ContactDetails.jsx
│           │   ├── FormGrid.jsx
│           │   ├── Link.jsx
│           │   ├── MessageList.jsx
│           │   ├── PasswordStrength.jsx
│           │   ├── PiBar.jsx
│           │   ├── Reply.jsx
│           │   ├── Subtitle.jsx
│           │   └── TagsForm.jsx
│           ├── index.jsx
│           ├── layouts/
│           │   ├── ContactBook.jsx
│           │   ├── Devices.jsx
│           │   ├── SigninPage.jsx
│           │   └── SignupPage.jsx
│           └── presenters/
│               ├── Code.jsx
│               ├── ComponentWrapper.jsx
│               └── index.js
├── doc/
│   ├── architecture/
│   │   ├── Repository_structure.md
│   │   └── assets/
│   │       └── stack_frontend_dev_2017-03-09.puml
│   ├── devops/
│   │   ├── continous-integration.md
│   │   ├── docker-&-registry.md
│   │   └── kube_survival_guide.md
│   ├── index.md
│   ├── install/
│   │   ├── frontend-development.md
│   │   ├── minikube-local-development.md
│   │   └── native-installation.md
│   ├── install.md
│   ├── monitoring-debug/
│   │   └── analyse-frontend-bundle.md
│   ├── release/
│   │   ├── Communication.md
│   │   ├── Guidelines.md
│   │   ├── README.md
│   │   └── deploy_kubernetes.md
│   ├── specifications/
│   │   ├── attachments/
│   │   │   ├── assets/
│   │   │   │   └── management.puml
│   │   │   └── index.md
│   │   ├── client/
│   │   │   ├── architecture.md
│   │   │   ├── frontend-data-flow.md
│   │   │   └── routing.md
│   │   ├── contact/
│   │   │   ├── assets/
│   │   │   │   └── discover_contact_from_email.uml
│   │   │   ├── index.md
│   │   │   └── vcard_doc.md
│   │   ├── discussions/
│   │   │   ├── assets/
│   │   │   │   └── delete_discussion.uml
│   │   │   └── delete_discussion.md
│   │   ├── email-protocol/
│   │   │   ├── assets/
│   │   │   │   ├── email-delivery-inbound-rpc.puml
│   │   │   │   ├── email-delivery-inbound.puml
│   │   │   │   ├── email-delivery-outbound.puml
│   │   │   │   ├── email-inbound-delivery-poc.puml
│   │   │   │   ├── imap-outbound-process.puml
│   │   │   │   └── smtp-delivery-inbound-closeup.puml
│   │   │   ├── imap-binaries.md
│   │   │   └── index.md
│   │   ├── identities/
│   │   │   ├── Remote-identities-creation-diagram.puml
│   │   │   ├── index.md
│   │   │   └── remote-identities.md
│   │   ├── message/
│   │   │   ├── assets/
│   │   │   │   ├── message-create-save-send.puml
│   │   │   │   ├── message-create-save-send_nats_async.puml
│   │   │   │   └── message_discussion_association.puml
│   │   │   └── index.md
│   │   ├── messages-drafts-discussions-routes/
│   │   │   └── index-fr.md
│   │   ├── messaging-system/
│   │   │   └── index.md
│   │   ├── notification/
│   │   │   ├── API-fr.md
│   │   │   ├── assets/
│   │   │   │   └── client-message-sequence.puml
│   │   │   └── frontend.md
│   │   ├── patch/
│   │   │   └── index.md
│   │   ├── protocol-implementation.md
│   │   ├── pwa/
│   │   │   ├── assets/
│   │   │   │   └── sequence.puml
│   │   │   └── pwa.md
│   │   ├── remote-identities/
│   │   │   ├── assets/
│   │   │   │   └── twitter-oauth.puml
│   │   │   ├── gmail.md
│   │   │   ├── oauth.md
│   │   │   └── twitter.md
│   │   ├── rest-api/
│   │   │   └── index.md
│   │   ├── scss-reference.md
│   │   ├── search/
│   │   │   └── index.md
│   │   ├── user-and-device-identification/
│   │   │   ├── assets/
│   │   │   │   ├── authenticate_new_device.uml
│   │   │   │   ├── create_user_and_device.uml
│   │   │   │   ├── user_and_device_authentication.uml
│   │   │   │   └── user_update_credential.uml
│   │   │   ├── index.md
│   │   │   └── revoke-devices.md
│   │   └── username/
│   │       └── index.md
│   ├── tools.md
│   └── welcome.md
└── src/
    ├── backend/
    │   ├── Dockerfile.caliopen-go
    │   ├── Dockerfile.caliopen-python
    │   ├── Dockerfile.cli
    │   ├── Dockerfile.cli-ml
    │   ├── Dockerfile.go-api
    │   ├── Dockerfile.go-lmtp
    │   ├── Dockerfile.identity-poller
    │   ├── Dockerfile.imap-worker
    │   ├── Dockerfile.mastodon-worker
    │   ├── Dockerfile.mq-worker
    │   ├── Dockerfile.py-api
    │   ├── Dockerfile.twitter-worker
    │   ├── brokers/
    │   │   ├── go.emails/
    │   │   │   ├── README.md
    │   │   │   ├── broker.go
    │   │   │   ├── email.go
    │   │   │   ├── encrypt.go
    │   │   │   ├── inbound.go
    │   │   │   └── outbound.go
    │   │   ├── go.mastodon/
    │   │   │   ├── broker.go
    │   │   │   ├── direct_messages.go
    │   │   │   ├── doc.go
    │   │   │   ├── inbound.go
    │   │   │   └── outbound.go
    │   │   └── go.twitter/
    │   │       ├── broker.go
    │   │       ├── direct_messages.go
    │   │       ├── doc.go
    │   │       ├── inbound.go
    │   │       └── outbound.go
    │   ├── components/
    │   │   ├── py.data/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_data/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── interface.py
    │   │   │   │   ├── provider.py
    │   │   │   │   └── store.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.pgp/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── MANIFEST.in
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_pgp/
    │   │   │   │   ├── __init__.py
    │   │   │   │   └── keys/
    │   │   │   │       ├── __init__.py
    │   │   │   │       ├── base.py
    │   │   │   │       ├── contact.py
    │   │   │   │       ├── discoverer.py
    │   │   │   │       ├── hkp.py
    │   │   │   │       ├── keybase.py
    │   │   │   │       └── rfc7929.py
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.pi/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_pi/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── features/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── contact.py
    │   │   │   │   │   ├── device.py
    │   │   │   │   │   ├── helpers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── histogram.py
    │   │   │   │   │   │   ├── importance_level.py
    │   │   │   │   │   │   ├── ingress_path.py
    │   │   │   │   │   │   └── spam.py
    │   │   │   │   │   ├── mail.py
    │   │   │   │   │   └── types.py
    │   │   │   │   ├── qualifiers/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── base.py
    │   │   │   │   │   ├── contact.py
    │   │   │   │   │   ├── device.py
    │   │   │   │   │   ├── mail.py
    │   │   │   │   │   ├── mastodon.py
    │   │   │   │   │   └── twitter.py
    │   │   │   │   └── tests/
    │   │   │   │       ├── fixtures/
    │   │   │   │       │   ├── dkim1.eml
    │   │   │   │       │   ├── pgp_crypted_1.eml
    │   │   │   │       │   ├── pgpsigned1.elm
    │   │   │   │       │   ├── spam1.eml
    │   │   │   │       │   ├── spam2.eml
    │   │   │   │       │   └── spam3.eml
    │   │   │   │       ├── test_features.py
    │   │   │   │       ├── test_importance_level.py
    │   │   │   │       └── test_spam.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   └── py.tag/
    │   │       ├── CHANGES.rst
    │   │       ├── README.rst
    │   │       ├── caliopen_tag/
    │   │       │   ├── __init__.py
    │   │       │   ├── models_manager/
    │   │       │   │   ├── __init__.py
    │   │       │   │   ├── data_manager.py
    │   │       │   │   └── manager.py
    │   │       │   ├── taggers/
    │   │       │   │   ├── __init__.py
    │   │       │   │   └── tagger.py
    │   │       │   ├── tests/
    │   │       │   │   ├── test_model_manager.py
    │   │       │   │   └── test_tag.py
    │   │       │   └── utils.py
    │   │       ├── requirements.deps
    │   │       ├── setup.cfg
    │   │       └── setup.py
    │   ├── configs/
    │   │   ├── apiv1-nginx.conf
    │   │   ├── apiv1-supervisord.conf
    │   │   ├── apiv1.ini
    │   │   ├── apiv2.yaml
    │   │   ├── caliopen-api.development.ini
    │   │   ├── caliopen.yaml
    │   │   ├── caliopen.yaml.template
    │   │   ├── idpoller.yaml
    │   │   ├── imapworker.yaml
    │   │   ├── lmtp.yaml
    │   │   ├── mastodonworker.yaml
    │   │   ├── swagger.json
    │   │   └── twitterworker.yaml
    │   ├── defs/
    │   │   ├── go-objects/
    │   │   │   ├── actions_payload.go
    │   │   │   ├── attachment.go
    │   │   │   ├── cache.go
    │   │   │   ├── common.go
    │   │   │   ├── configs.go
    │   │   │   ├── constants.go
    │   │   │   ├── contact.go
    │   │   │   ├── credentials.go
    │   │   │   ├── crypto_keys.go
    │   │   │   ├── device.go
    │   │   │   ├── discussion.go
    │   │   │   ├── email.go
    │   │   │   ├── errors.go
    │   │   │   ├── external_references.go
    │   │   │   ├── im.go
    │   │   │   ├── location.go
    │   │   │   ├── message.go
    │   │   │   ├── nats.go
    │   │   │   ├── notification.go
    │   │   │   ├── notification_test.go
    │   │   │   ├── organization.go
    │   │   │   ├── participant.go
    │   │   │   ├── participants_test.go
    │   │   │   ├── phone.go
    │   │   │   ├── postal_address.go
    │   │   │   ├── privacy_features.go
    │   │   │   ├── privacy_index.go
    │   │   │   ├── provider.go
    │   │   │   ├── raw_message.go
    │   │   │   ├── search.go
    │   │   │   ├── settings.go
    │   │   │   ├── social_identity.go
    │   │   │   ├── tag.go
    │   │   │   ├── tls.go
    │   │   │   ├── user.go
    │   │   │   ├── user_identity.go
    │   │   │   ├── username.go
    │   │   │   └── uuid.go
    │   │   ├── nats-messages/
    │   │   │   ├── IMAPworkers_FetchOrder.yaml
    │   │   │   ├── SMTPqueue_ack_msg.yaml
    │   │   │   ├── UpdateContactPI_msg.yaml
    │   │   │   ├── inboundSMTP_deliver_msg.yaml
    │   │   │   └── outboundSMTP_deliver_msg.yaml
    │   │   ├── notifiers/
    │   │   │   └── templates/
    │   │   │       ├── email-device-validation.yaml
    │   │   │       ├── email-onboarding.yaml
    │   │   │       ├── email-reset-password-link.yaml
    │   │   │       └── email-welcome.yaml
    │   │   └── rest-api/
    │   │       ├── objects/
    │   │       │   ├── Actions.yaml
    │   │       │   ├── Attachment.yaml
    │   │       │   ├── Authentication.yaml
    │   │       │   ├── Contact.yaml
    │   │       │   ├── ContactIdentity.yaml
    │   │       │   ├── DefaultDevice.yaml
    │   │       │   ├── Device.yaml
    │   │       │   ├── DeviceLocation.yaml
    │   │       │   ├── Discussion.yaml
    │   │       │   ├── ECKey.yaml
    │   │       │   ├── Email.yaml
    │   │       │   ├── Error.yaml
    │   │       │   ├── ExternalReferences.yaml
    │   │       │   ├── IM.yaml
    │   │       │   ├── Identity.yaml
    │   │       │   ├── Message.yaml
    │   │       │   ├── MessageV2.yaml
    │   │       │   ├── NewContact.yaml
    │   │       │   ├── NewDevice.yaml
    │   │       │   ├── NewEmail.yaml
    │   │       │   ├── NewIM.yaml
    │   │       │   ├── NewMessage.yaml
    │   │       │   ├── NewMessageV2.yaml
    │   │       │   ├── NewOrganization.yaml
    │   │       │   ├── NewPhone.yaml
    │   │       │   ├── NewPostalAddress.yaml
    │   │       │   ├── NewPublicKey.yaml
    │   │       │   ├── NewSocialIdentity.yaml
    │   │       │   ├── NewTag.yaml
    │   │       │   ├── NewUser.yaml
    │   │       │   ├── NewUserIdentity.yaml
    │   │       │   ├── Notification.yaml
    │   │       │   ├── Organization.yaml
    │   │       │   ├── PI.yaml
    │   │       │   ├── PIMessage.yaml
    │   │       │   ├── Participant.yaml
    │   │       │   ├── ParticipantSuggest.yaml
    │   │       │   ├── Phone.yaml
    │   │       │   ├── PostalAddress.yaml
    │   │       │   ├── PrivacyFeatures.yaml
    │   │       │   ├── PublicKey.yaml
    │   │       │   ├── SearchResponse.yaml
    │   │       │   ├── Settings.yaml
    │   │       │   ├── ShortContact.yaml
    │   │       │   ├── SocialIdentity.yaml
    │   │       │   ├── Tag.yaml
    │   │       │   ├── User.yaml
    │   │       │   └── UserIdentity.yaml
    │   │       ├── paths/
    │   │       │   ├── authentications.yaml
    │   │       │   ├── contacts.yaml
    │   │       │   ├── contactsV2.yaml
    │   │       │   ├── devices.yaml
    │   │       │   ├── discussions.yaml
    │   │       │   ├── files.yaml
    │   │       │   ├── hashdiscussion.yaml
    │   │       │   ├── identities.yaml
    │   │       │   ├── imports.yaml
    │   │       │   ├── me.yaml
    │   │       │   ├── messages.yaml
    │   │       │   ├── messagesV2.yaml
    │   │       │   ├── notifications.yaml
    │   │       │   ├── participants.yaml
    │   │       │   ├── passwords.yaml
    │   │       │   ├── providers.yaml
    │   │       │   ├── raws.yaml
    │   │       │   ├── search.yaml
    │   │       │   ├── settings.yaml
    │   │       │   ├── tags.yaml
    │   │       │   └── users.yaml
    │   │       └── swagger-root.yaml
    │   ├── doc/
    │   │   └── api/
    │   │       ├── README.md
    │   │       └── swagger.html
    │   ├── interfaces/
    │   │   ├── NATS/
    │   │   │   ├── go.mockednats/
    │   │   │   │   └── nats.go
    │   │   │   └── py.client/
    │   │   │       ├── CHANGES.rst
    │   │   │       ├── MANIFEST.in
    │   │   │       ├── README.rst
    │   │   │       ├── caliopen_nats/
    │   │   │       │   ├── __init__.py
    │   │   │       │   ├── delivery.py
    │   │   │       │   ├── listener.py
    │   │   │       │   └── subscribers.py
    │   │   │       ├── requirements.deps
    │   │   │       ├── setup.cfg
    │   │   │       └── setup.py
    │   │   └── REST/
    │   │       ├── go.server/
    │   │       │   ├── README.md
    │   │       │   ├── api_server.go
    │   │       │   ├── cmd/
    │   │       │   │   └── caliopen_rest/
    │   │       │   │       ├── cli_cmds/
    │   │       │   │       │   ├── root.go
    │   │       │   │       │   └── serve.go
    │   │       │   │       └── main.go
    │   │       │   ├── dump_request.go
    │   │       │   ├── errors.go
    │   │       │   ├── middlewares/
    │   │       │   │   ├── authentication.go
    │   │       │   │   ├── config.go
    │   │       │   │   └── swagger.go
    │   │       │   ├── operations/
    │   │       │   │   ├── contacts/
    │   │       │   │   │   ├── Identities.go
    │   │       │   │   │   ├── contacts.go
    │   │       │   │   │   └── keys.go
    │   │       │   │   ├── devices/
    │   │       │   │   │   └── devices.go
    │   │       │   │   ├── discussions/
    │   │       │   │   │   └── discussions.go
    │   │       │   │   ├── helpers.go
    │   │       │   │   ├── identities/
    │   │       │   │   │   └── identities.go
    │   │       │   │   ├── imports/
    │   │       │   │   │   └── import.go
    │   │       │   │   ├── messages/
    │   │       │   │   │   ├── actions.go
    │   │       │   │   │   ├── attachments.go
    │   │       │   │   │   └── messages.go
    │   │       │   │   ├── notifications/
    │   │       │   │   │   └── notifications.go
    │   │       │   │   ├── participants/
    │   │       │   │   │   ├── discussion.go
    │   │       │   │   │   └── suggest.go
    │   │       │   │   ├── providers/
    │   │       │   │   │   ├── oauth-test.html
    │   │       │   │   │   └── providers.go
    │   │       │   │   ├── search.go
    │   │       │   │   ├── tags/
    │   │       │   │   │   └── tags.go
    │   │       │   │   └── users/
    │   │       │   │       ├── user.go
    │   │       │   │       └── username.go
    │   │       │   └── proxy.go
    │   │       └── py.server/
    │   │           ├── CHANGES.rst
    │   │           ├── MANIFEST.in
    │   │           ├── README.rst
    │   │           ├── caliopen_api/
    │   │           │   ├── __init__.py
    │   │           │   ├── base/
    │   │           │   │   ├── __init__.py
    │   │           │   │   ├── config.py
    │   │           │   │   ├── context.py
    │   │           │   │   ├── deserializer.py
    │   │           │   │   ├── errors.py
    │   │           │   │   ├── exception.py
    │   │           │   │   └── renderer.py
    │   │           │   ├── discussion/
    │   │           │   │   ├── __init__.py
    │   │           │   │   ├── config.py
    │   │           │   │   └── participants.py
    │   │           │   ├── message/
    │   │           │   │   ├── __init__.py
    │   │           │   │   ├── config.py
    │   │           │   │   └── message.py
    │   │           │   └── user/
    │   │           │       ├── __init__.py
    │   │           │       ├── authentication.py
    │   │           │       ├── config.py
    │   │           │       ├── contact.py
    │   │           │       ├── imports.py
    │   │           │       ├── settings.py
    │   │           │       ├── user.py
    │   │           │       └── util.py
    │   │           ├── requirements.deps
    │   │           ├── setup.cfg
    │   │           └── setup.py
    │   ├── main/
    │   │   ├── go.backends/
    │   │   │   ├── AttachmentsInterfaces.go
    │   │   │   ├── CacheInterfaces.go
    │   │   │   ├── ContactsInterfaces.go
    │   │   │   ├── CredentialsInterfaces.go
    │   │   │   ├── DevicesInterfaces.go
    │   │   │   ├── DiscussionsInterface.go
    │   │   │   ├── IdentitiesInterface.go
    │   │   │   ├── KeysInterfaces.go
    │   │   │   ├── LDAInterfaces.go
    │   │   │   ├── MessagesInterfaces.go
    │   │   │   ├── NotificationsInterfaces.go
    │   │   │   ├── ProvidersInterfaces.go
    │   │   │   ├── RESTInterfaces.go
    │   │   │   ├── TagsInterfaces.go
    │   │   │   ├── UrisInterface.go
    │   │   │   ├── UsersInterfaces.go
    │   │   │   ├── backendstest/
    │   │   │   │   ├── APIstore.go
    │   │   │   │   ├── Attachments.go
    │   │   │   │   ├── Cache.go
    │   │   │   │   ├── Contacts.go
    │   │   │   │   ├── Credentials.go
    │   │   │   │   ├── Devices.go
    │   │   │   │   ├── Discussions.go
    │   │   │   │   ├── Identities.go
    │   │   │   │   ├── Keys.go
    │   │   │   │   ├── LDA.go
    │   │   │   │   ├── Messages.go
    │   │   │   │   ├── Notifications.go
    │   │   │   │   ├── Providers.go
    │   │   │   │   ├── Tags.go
    │   │   │   │   ├── UrisInterface.go
    │   │   │   │   ├── UserNames.go
    │   │   │   │   ├── Users.go
    │   │   │   │   └── testdata.go
    │   │   │   ├── cache/
    │   │   │   │   ├── authentication.go
    │   │   │   │   ├── cache.go
    │   │   │   │   ├── devicevalidation.go
    │   │   │   │   ├── devicevalidation_test.go
    │   │   │   │   ├── oauthsessions.go
    │   │   │   │   ├── passwordreset.go
    │   │   │   │   └── redis.go
    │   │   │   ├── index/
    │   │   │   │   └── elasticsearch/
    │   │   │   │       ├── broad_search.go
    │   │   │   │       ├── contacts.go
    │   │   │   │       ├── discussions.go
    │   │   │   │       ├── elasticsearch.go
    │   │   │   │       ├── messages.go
    │   │   │   │       └── user_recipients_lookup.go
    │   │   │   └── store/
    │   │   │       ├── cassandra/
    │   │   │       │   ├── attachments.go
    │   │   │       │   ├── cassandra.go
    │   │   │       │   ├── contacts.go
    │   │   │       │   ├── contacts_test.go
    │   │   │       │   ├── credentials.go
    │   │   │       │   ├── devices.go
    │   │   │       │   ├── discussions.go
    │   │   │       │   ├── discussions_test.go
    │   │   │       │   ├── emails.go
    │   │   │       │   ├── identities.go
    │   │   │       │   ├── keys.go
    │   │   │       │   ├── lookups.go
    │   │   │       │   ├── messages.go
    │   │   │       │   ├── notifications.go
    │   │   │       │   ├── participant_lookup.go
    │   │   │       │   ├── providers.go
    │   │   │       │   ├── raw_messages.go
    │   │   │       │   ├── related.go
    │   │   │       │   ├── settings.go
    │   │   │       │   ├── tags.go
    │   │   │       │   ├── usernames.go
    │   │   │       │   └── users.go
    │   │   │       ├── object_store/
    │   │   │       │   ├── attachments.go
    │   │   │       │   ├── minio.go
    │   │   │       │   ├── objects.go
    │   │   │       │   └── raw_messages.go
    │   │   │       └── vault/
    │   │   │           ├── credentials.go
    │   │   │           ├── hvault_interface.go
    │   │   │           └── vault_client.go
    │   │   ├── go.main/
    │   │   │   ├── caliopen.go
    │   │   │   ├── contact/
    │   │   │   │   ├── contact.go
    │   │   │   │   ├── contact_test.go
    │   │   │   │   └── vcard.go
    │   │   │   ├── facilities/
    │   │   │   │   ├── Messaging/
    │   │   │   │   │   ├── facility.go
    │   │   │   │   │   └── facility_test.go
    │   │   │   │   ├── Notifications/
    │   │   │   │   │   ├── batch.go
    │   │   │   │   │   ├── batch_test.go
    │   │   │   │   │   ├── email.go
    │   │   │   │   │   ├── facility.go
    │   │   │   │   │   ├── queue.go
    │   │   │   │   │   └── templating.go
    │   │   │   │   └── REST/
    │   │   │   │       ├── RESTfacility.go
    │   │   │   │       ├── attachment.go
    │   │   │   │       ├── contacts.go
    │   │   │   │       ├── contacts_test.go
    │   │   │   │       ├── devices.go
    │   │   │   │       ├── devices_test.go
    │   │   │   │       ├── discussions.go
    │   │   │   │       ├── draft.go
    │   │   │   │       ├── identities.go
    │   │   │   │       ├── keys.go
    │   │   │   │       ├── message.go
    │   │   │   │       ├── nats.go
    │   │   │   │       ├── providers.go
    │   │   │   │       ├── search.go
    │   │   │   │       ├── settings.go
    │   │   │   │       ├── suggest_participants.go
    │   │   │   │       ├── tags.go
    │   │   │   │       ├── username.go
    │   │   │   │       └── users.go
    │   │   │   ├── helpers/
    │   │   │   │   ├── contact.go
    │   │   │   │   ├── discussion.go
    │   │   │   │   ├── discussion_test.go
    │   │   │   │   ├── filesystem.go
    │   │   │   │   ├── misc.go
    │   │   │   │   ├── netTest.go
    │   │   │   │   ├── patch.go
    │   │   │   │   └── uuid.go
    │   │   │   ├── messages/
    │   │   │   │   └── messages.go
    │   │   │   ├── pi/
    │   │   │   │   ├── identities.go
    │   │   │   │   └── message.go
    │   │   │   └── users/
    │   │   │       ├── oauth2.go
    │   │   │       └── password.go
    │   │   ├── py.main/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── MANIFEST.in
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_main/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── common/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── base.py
    │   │   │   │   │   │   ├── pubkey.py
    │   │   │   │   │   │   └── related.py
    │   │   │   │   │   ├── errors.py
    │   │   │   │   │   ├── helpers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── normalize.py
    │   │   │   │   │   │   └── strings.py
    │   │   │   │   │   ├── interfaces/
    │   │   │   │   │   │   ├── IO.py
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── parser.py
    │   │   │   │   │   │   └── storage.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── base.py
    │   │   │   │   │   │   └── tag.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── pubkey.py
    │   │   │   │   │   │   ├── tag.py
    │   │   │   │   │   │   └── types.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── pubkey.py
    │   │   │   │   │       └── tag.py
    │   │   │   │   ├── contact/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── contact.py
    │   │   │   │   │   │   ├── email.py
    │   │   │   │   │   │   ├── identity.py
    │   │   │   │   │   │   ├── im.py
    │   │   │   │   │   │   ├── organization.py
    │   │   │   │   │   │   ├── phone.py
    │   │   │   │   │   │   └── postal_address.py
    │   │   │   │   │   ├── parameters.py
    │   │   │   │   │   ├── parsers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── vcard.py
    │   │   │   │   │   ├── returns.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── contact.py
    │   │   │   │   │       └── contact_index.py
    │   │   │   │   ├── device/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core.py
    │   │   │   │   │   ├── parameters.py
    │   │   │   │   │   └── store.py
    │   │   │   │   ├── discussion/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── discussion.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── discussion.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── discussion.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── discussion_index.py
    │   │   │   │   │       └── discussion_lookup.py
    │   │   │   │   ├── message/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── external_references.py
    │   │   │   │   │   │   └── raw.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── attachment.py
    │   │   │   │   │   │   ├── external_references.py
    │   │   │   │   │   │   └── message.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── attachment.py
    │   │   │   │   │   │   ├── draft.py
    │   │   │   │   │   │   ├── external_references.py
    │   │   │   │   │   │   └── message.py
    │   │   │   │   │   ├── parsers/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   ├── mail.py
    │   │   │   │   │   │   ├── mastodon.py
    │   │   │   │   │   │   └── twitter.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── attachment.py
    │   │   │   │   │       ├── attachment_index.py
    │   │   │   │   │       ├── external_references.py
    │   │   │   │   │       ├── external_references_index.py
    │   │   │   │   │       ├── message.py
    │   │   │   │   │       ├── message_index.py
    │   │   │   │   │       └── raw.py
    │   │   │   │   ├── notification/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core.py
    │   │   │   │   │   └── store.py
    │   │   │   │   ├── participant/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── participant.py
    │   │   │   │   │   ├── objects/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── participant.py
    │   │   │   │   │   ├── parameters/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── participant.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── participant.py
    │   │   │   │   │       └── participant_index.py
    │   │   │   │   ├── pi/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── objects.py
    │   │   │   │   │   └── parameters.py
    │   │   │   │   ├── protocol/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── core/
    │   │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   │   └── provider.py
    │   │   │   │   │   └── store/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       └── provider.py
    │   │   │   │   ├── tests/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── fixtures/
    │   │   │   │   │   │   ├── mail/
    │   │   │   │   │   │   │   ├── pgp_crypted_1.eml
    │   │   │   │   │   │   │   └── pgp_signed_1.eml
    │   │   │   │   │   │   └── vcard/
    │   │   │   │   │   │       ├── multi.vcf
    │   │   │   │   │   │       ├── rfc2425-1.vcard
    │   │   │   │   │   │       ├── rfc2425-2.vcard
    │   │   │   │   │   │       ├── rfc2425-3.vcard
    │   │   │   │   │   │       ├── rfc2426-1.vcard
    │   │   │   │   │   │       ├── rfc2426-2.vcard
    │   │   │   │   │   │       ├── rfc2426-3.vcard
    │   │   │   │   │   │       ├── rfc2426-4.vcard
    │   │   │   │   │   │       ├── rfc2426-5.vcard
    │   │   │   │   │   │       ├── vcard1.vcf
    │   │   │   │   │   │       ├── vcard2.vcf
    │   │   │   │   │   │       └── vcard3.vcf
    │   │   │   │   │   └── parsers/
    │   │   │   │   │       ├── __init__.py
    │   │   │   │   │       ├── test_email.py
    │   │   │   │   │       ├── test_mail.py
    │   │   │   │   │       └── test_vcard.py
    │   │   │   │   └── user/
    │   │   │   │       ├── __init__.py
    │   │   │   │       ├── core/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── identity.py
    │   │   │   │       │   ├── setups.py
    │   │   │   │       │   └── user.py
    │   │   │   │       ├── helpers/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── mergePatch.py
    │   │   │   │       │   └── validators.py
    │   │   │   │       ├── objects/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── device.py
    │   │   │   │       │   ├── identity.py
    │   │   │   │       │   ├── settings.py
    │   │   │   │       │   └── tag.py
    │   │   │   │       ├── parameters/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   ├── identity.py
    │   │   │   │       │   ├── settings.py
    │   │   │   │       │   ├── tag.py
    │   │   │   │       │   └── user.py
    │   │   │   │       ├── returns/
    │   │   │   │       │   ├── __init__.py
    │   │   │   │       │   └── user.py
    │   │   │   │       └── store/
    │   │   │   │           ├── __init__.py
    │   │   │   │           ├── identity.py
    │   │   │   │           ├── tag.py
    │   │   │   │           ├── user.py
    │   │   │   │           └── user_index.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   └── py.storage/
    │   │       ├── CHANGES.rst
    │   │       ├── MANIFEST.in
    │   │       ├── README.rst
    │   │       ├── caliopen_storage/
    │   │       │   ├── __init__.py
    │   │       │   ├── config.py
    │   │       │   ├── core/
    │   │       │   │   ├── __init__.py
    │   │       │   │   ├── base.py
    │   │       │   │   ├── mixin.py
    │   │       │   │   └── registry.py
    │   │       │   ├── exception.py
    │   │       │   ├── helpers/
    │   │       │   │   ├── __init__.py
    │   │       │   │   ├── connection.py
    │   │       │   │   └── json.py
    │   │       │   ├── parameters.py
    │   │       │   ├── returns.py
    │   │       │   └── store/
    │   │       │       ├── __init__.py
    │   │       │       ├── mixin.py
    │   │       │       └── model.py
    │   │       ├── setup.cfg
    │   │       └── setup.py
    │   ├── protocols/
    │   │   ├── go.imap/
    │   │   │   ├── cmd/
    │   │   │   │   ├── imapctl/
    │   │   │   │   │   ├── cli_cmds/
    │   │   │   │   │   │   ├── addremote.go
    │   │   │   │   │   │   ├── fullfetch.go
    │   │   │   │   │   │   ├── root.go
    │   │   │   │   │   │   └── syncremote.go
    │   │   │   │   │   └── main.go
    │   │   │   │   └── imapworker/
    │   │   │   │       ├── cli_cmds/
    │   │   │   │       │   ├── root.go
    │   │   │   │       │   └── start.go
    │   │   │   │       └── main.go
    │   │   │   ├── config.go
    │   │   │   ├── fetcher.go
    │   │   │   ├── imap.go
    │   │   │   ├── imap_test.go
    │   │   │   ├── lda.go
    │   │   │   ├── sender.go
    │   │   │   ├── sender_test.go
    │   │   │   ├── worker.go
    │   │   │   └── worker_test.go
    │   │   ├── go.mastodon/
    │   │   │   ├── account.go
    │   │   │   ├── cmd/
    │   │   │   │   └── mastodonworker/
    │   │   │   │       ├── cli_cmds/
    │   │   │   │       │   ├── root.go
    │   │   │   │       │   └── start.go
    │   │   │   │       └── main.go
    │   │   │   ├── messaging.go
    │   │   │   └── worker.go
    │   │   ├── go.smtp/
    │   │   │   ├── cmd/
    │   │   │   │   └── caliopen_lmtpd/
    │   │   │   │       ├── cli_cmds/
    │   │   │   │       │   ├── root.go
    │   │   │   │       │   └── serve.go
    │   │   │   │       └── main.go
    │   │   │   ├── config.go
    │   │   │   ├── envelope.go
    │   │   │   ├── lda.go
    │   │   │   ├── lmtpd.go
    │   │   │   ├── oauth.go
    │   │   │   ├── protocol.go
    │   │   │   ├── receiver.go
    │   │   │   ├── server.go
    │   │   │   └── submitter.go
    │   │   └── go.twitter/
    │   │       ├── account.go
    │   │       ├── account_test.go
    │   │       ├── cmd/
    │   │       │   └── twitterworker/
    │   │       │       ├── cli_cmds/
    │   │       │       │   ├── root.go
    │   │       │       │   └── start.go
    │   │       │       └── main.go
    │   │       ├── messaging.go
    │   │       ├── messaging_test.go
    │   │       ├── worker.go
    │   │       └── worker_test.go
    │   ├── tools/
    │   │   ├── go.CLI/
    │   │   │   └── cmd/
    │   │   │       └── gocaliopen/
    │   │   │           ├── cli_cmds/
    │   │   │           │   ├── changeIdentitiyEmailProtocol.go
    │   │   │           │   ├── changeUserIdentitiesCredentialsKeys.go
    │   │   │           │   ├── fixMissingParticipants.go
    │   │   │           │   ├── identitiesMigration.go
    │   │   │           │   └── root.go
    │   │   │           └── main.go
    │   │   ├── py.CLI/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_cli/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── cli.py
    │   │   │   │   ├── commands/
    │   │   │   │   │   ├── __init__.py
    │   │   │   │   │   ├── compute.py
    │   │   │   │   │   ├── copy_model.py
    │   │   │   │   │   ├── create_user.py
    │   │   │   │   │   ├── dump_indexes_mappings.py
    │   │   │   │   │   ├── dump_model.py
    │   │   │   │   │   ├── import_email.py
    │   │   │   │   │   ├── import_vcard.py
    │   │   │   │   │   ├── inject_email.py
    │   │   │   │   │   ├── migrate_index.py
    │   │   │   │   │   ├── reserved_names.py
    │   │   │   │   │   ├── resync_index.py
    │   │   │   │   │   ├── resync_shard_index.py
    │   │   │   │   │   ├── setup.py
    │   │   │   │   │   ├── setup_notifications_ttls.py
    │   │   │   │   │   ├── setup_storage.py
    │   │   │   │   │   └── shell.py
    │   │   │   │   └── utils/
    │   │   │   │       ├── __init__.py
    │   │   │   │       └── user_token.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.ML/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_climl/
    │   │   │   │   ├── __init__.py
    │   │   │   │   └── cli.py
    │   │   │   ├── requirements.deps
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   ├── py.doc/
    │   │   │   ├── CHANGES.rst
    │   │   │   ├── README.rst
    │   │   │   ├── caliopen_api_doc/
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── config.py
    │   │   │   │   └── swagger-ui/
    │   │   │   │       ├── css/
    │   │   │   │       │   ├── print.css
    │   │   │   │       │   ├── reset.css
    │   │   │   │       │   ├── screen.css
    │   │   │   │       │   ├── style.css
    │   │   │   │       │   └── typography.css
    │   │   │   │       ├── index.html
    │   │   │   │       ├── lang/
    │   │   │   │       │   ├── ca.js
    │   │   │   │       │   ├── el.js
    │   │   │   │       │   ├── en.js
    │   │   │   │       │   ├── es.js
    │   │   │   │       │   ├── fr.js
    │   │   │   │       │   ├── geo.js
    │   │   │   │       │   ├── it.js
    │   │   │   │       │   ├── ja.js
    │   │   │   │       │   ├── ko-kr.js
    │   │   │   │       │   ├── pl.js
    │   │   │   │       │   ├── pt.js
    │   │   │   │       │   ├── ru.js
    │   │   │   │       │   ├── tr.js
    │   │   │   │       │   ├── translator.js
    │   │   │   │       │   └── zh-cn.js
    │   │   │   │       ├── lib/
    │   │   │   │       │   ├── backbone-min.js
    │   │   │   │       │   ├── es5-shim.js
    │   │   │   │       │   ├── handlebars-4.0.5.js
    │   │   │   │       │   ├── highlight.9.1.0.pack.js
    │   │   │   │       │   ├── highlight.9.1.0.pack_extended.js
    │   │   │   │       │   ├── marked.js
    │   │   │   │       │   ├── object-assign-pollyfill.js
    │   │   │   │       │   └── swagger-oauth.js
    │   │   │   │       ├── o2c.html
    │   │   │   │       └── swagger-ui.js
    │   │   │   ├── setup.cfg
    │   │   │   └── setup.py
    │   │   └── py.migrate/
    │   │       ├── CHANGES.rst
    │   │       ├── README.rst
    │   │       ├── caliopen_migrate/
    │   │       │   ├── __init__.py
    │   │       │   ├── cli.py
    │   │       │   ├── shards.py
    │   │       │   ├── user.py
    │   │       │   └── welcome_message.py
    │   │       ├── setup.cfg
    │   │       └── setup.py
    │   └── workers/
    │       └── go.remoteIDs/
    │           ├── cmd/
    │           │   └── idpoller/
    │           │       ├── cli_cmds/
    │           │       │   ├── root.go
    │           │       │   └── start.go
    │           │       └── main.go
    │           ├── identities.go
    │           ├── identities_test.go
    │           ├── idpoller.go
    │           ├── idpollertest/
    │           │   └── testsreplies.go
    │           ├── jobs.go
    │           ├── jobs_test.go
    │           ├── messaging.go
    │           ├── messaging_test.go
    │           ├── scheduler.go
    │           └── scheduler_test.go
    └── frontend/
        ├── maintenance/
        │   ├── Dockerfile
        │   ├── README.md
        │   ├── config/
        │   │   └── nginx-config-maintenance.conf
        │   ├── package.json
        │   └── src/
        │       ├── assets/
        │       │   ├── css/
        │       │   │   └── style.css
        │       │   ├── js/
        │       │   │   └── init.js
        │       │   └── scss/
        │       │       ├── params/
        │       │       │   ├── _fonts.scss
        │       │       │   ├── _grid.scss
        │       │       │   ├── _images.scss
        │       │       │   └── _variables.scss
        │       │       └── style.scss
        │       └── index.html
        ├── not_found/
        │   ├── 404.html
        │   └── assets/
        │       └── app.client.e4ae8e333ea54a53ba14.css
        └── web_application/
            ├── .babelrc
            ├── .dockerignore
            ├── .eslintrc.json
            ├── .gitignore
            ├── .prettierignore
            ├── .prettierrc.js
            ├── .stylelintrc.yml
            ├── CONTRIBUTING.md
            ├── Dockerfile
            ├── Dockerfile.caliopen-node
            ├── README.md
            ├── __mocks__/
            │   ├── fileMock.js
            │   └── styleMock.js
            ├── bin/
            │   ├── dev-server
            │   └── server
            ├── config/
            │   ├── client.default.js
            │   ├── server.default.js
            │   └── server.env-var.js
            ├── lingui.config.ts
            ├── locale/
            │   ├── de/
            │   │   └── messages.json
            │   ├── en/
            │   │   └── messages.json
            │   ├── es/
            │   │   └── messages.json
            │   └── fr/
            │       └── messages.json
            ├── package.json
            ├── postcss.config.js
            ├── public/
            │   └── privacy-policy.html
            ├── server/
            │   ├── api/
            │   │   ├── index.js
            │   │   └── lib/
            │   │       ├── api.ts
            │   │       └── sub-request-manager.js
            │   ├── app.ts
            │   ├── assets/
            │   │   └── index.js
            │   ├── auth/
            │   │   ├── index.js
            │   │   ├── lib/
            │   │   │   ├── cookie.ts
            │   │   │   ├── redirect.ts
            │   │   │   └── seal.ts
            │   │   ├── middlewares/
            │   │   │   ├── decode-cookie.ts
            │   │   │   └── index.ts
            │   │   └── router/
            │   │       ├── index.js
            │   │       ├── signin.js
            │   │       └── signup.ts
            │   ├── config/
            │   │   └── index.js
            │   ├── error/
            │   │   ├── components/
            │   │   │   └── Error/
            │   │   │       └── index.jsx
            │   │   ├── consts.ts
            │   │   ├── index.js
            │   │   └── middlewares/
            │   │       └── catch-error.js
            │   ├── express-react/
            │   │   ├── create-engine.js
            │   │   ├── index.js
            │   │   └── view.js
            │   ├── index.js
            │   ├── logger/
            │   │   ├── getLogger.js
            │   │   ├── index.js
            │   │   └── middlewares/
            │   │       └── httpLog.js
            │   └── ssr/
            │       ├── components/
            │       │   └── Bootstrap.tsx
            │       ├── index.js
            │       └── ssr-middleware.ts
            ├── src/
            │   ├── App.tsx
            │   ├── app.scss
            │   ├── components/
            │   │   ├── ActionBar/
            │   │   │   ├── components/
            │   │   │   │   ├── ActionBarButton/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   └── ActionBarWrapper/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── styles.scss
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── AdvancedSelectFieldGroup/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── AppLoader/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Badge/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── BlockList/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Brand/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Button/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Callout/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Checkbox/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── CheckboxFieldGroup/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Confirm/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── DatePickerGroup/
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── DefList/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── Dropdown/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   ├── services/
            │   │   │   │   ├── getDropdownStyle.spec.ts
            │   │   │   │   └── getDropdownStyle.ts
            │   │   │   └── style.scss
            │   │   ├── DropdownMenu/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── FieldErrors/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── FieldGroup/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Fieldset/
            │   │   │   ├── components/
            │   │   │   │   └── Legend/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── FileSize/
            │   │   │   ├── index.spec.tsx
            │   │   │   └── index.tsx
            │   │   ├── FormGrid/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Icon/
            │   │   │   ├── __snapshots__/
            │   │   │   │   └── index.spec.tsx.snap
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── InfiniteScroll/
            │   │   │   └── index.jsx
            │   │   ├── InputFile/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── InputFileGroup/
            │   │   │   ├── components/
            │   │   │   │   └── File/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── InputText/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Label/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Link/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── MenuBar/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── MessageDate/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── Modal/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── NavList/
            │   │   │   ├── components/
            │   │   │   │   └── NavItem.tsx
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── PageTitle/
            │   │   │   ├── index.jsx
            │   │   │   └── presenter.jsx
            │   │   ├── ParticipantsIconLetter/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── PasswordStrength/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── PiBar/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── PlaceholderBlock/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── PlaceholderList/
            │   │   │   ├── index.scss
            │   │   │   └── index.tsx
            │   │   ├── RadioFieldGroup/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── RawButton/
            │   │   │   └── index.tsx
            │   │   ├── Section/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── SelectFieldGroup/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── SidebarLayout/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Spinner/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Subtitle/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Switch/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── TextBlock/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── TextFieldGroup/
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── TextList/
            │   │   │   ├── components/
            │   │   │   │   └── TextItem.tsx
            │   │   │   ├── index.spec.jsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Textarea/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── TextareaFieldGroup/
            │   │   │   ├── index.jsx
            │   │   │   ├── index.spec.jsx
            │   │   │   └── style.scss
            │   │   ├── Title/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── VerticalMenu/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   └── index.js
            │   ├── global.d.ts
            │   ├── hooks/
            │   │   └── forwardedRef.ts
            │   ├── image.d.ts
            │   ├── index.jsx
            │   ├── layouts/
            │   │   ├── AboutPage/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── AuthPage/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── ErrorBoundary/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── Page/
            │   │   │   ├── components/
            │   │   │   │   ├── Footer/
            │   │   │   │   │   ├── footer.scss
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── HorizontalScroll/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── InstallButton/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── Navbar/
            │   │   │   │   │   └── components/
            │   │   │   │   │       ├── ApplicationTab/
            │   │   │   │   │       │   ├── application-tab.scss
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── ContactAssociationTab/
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── ContactTab/
            │   │   │   │   │       │   └── index.tsx
            │   │   │   │   │       ├── DiscussionTab/
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── ItemButton/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       ├── ItemLink/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       ├── NavbarItem/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       ├── SearchTab/
            │   │   │   │   │       │   └── index.jsx
            │   │   │   │   │       ├── Tab/
            │   │   │   │   │       │   ├── index.jsx
            │   │   │   │   │       │   └── style.scss
            │   │   │   │   │       └── index.js
            │   │   │   │   ├── Navigation/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   ├── style.scss
            │   │   │   │   │   └── withTabs.jsx
            │   │   │   │   ├── NotificationCenter/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TakeATour/
            │   │   │   │       ├── components/
            │   │   │   │       │   ├── Guide/
            │   │   │   │       │   │   └── index.jsx
            │   │   │   │       │   ├── Tour/
            │   │   │   │       │   │   └── index.jsx
            │   │   │   │       │   └── TourPortal/
            │   │   │   │       │       ├── index.jsx
            │   │   │   │       │       └── style.scss
            │   │   │   │       ├── index.js
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── header.scss
            │   │   │   ├── index.jsx
            │   │   │   ├── navbar.scss
            │   │   │   └── style.scss
            │   │   ├── PageContainer/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── SearchResults/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── Settings/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   └── User/
            │   │       ├── index.js
            │   │       ├── presenter.jsx
            │   │       └── styles.scss
            │   ├── modules/
            │   │   ├── a11y/
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       └── tabIndexes.js
            │   │   ├── avatar/
            │   │   │   ├── components/
            │   │   │   │   ├── AuthorAvatarLetter/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── index.spec.jsx
            │   │   │   │   ├── AvatarLetter/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── services/
            │   │   │   │   │   │   └── stylesheet-helper/
            │   │   │   │   │   │       ├── index.js
            │   │   │   │   │   │       └── index.spec.js
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── AvatarLetterWrapper/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── ContactAvatarLetter/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── index.spec.jsx
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       └── stylesheet-helper/
            │   │   │           ├── index.js
            │   │   │           └── index.spec.js
            │   │   ├── contact/
            │   │   │   ├── actions/
            │   │   │   │   ├── deleteContacts.js
            │   │   │   │   ├── getContact.ts
            │   │   │   │   ├── loadMoreContacts.ts
            │   │   │   │   └── updateContact.js
            │   │   │   ├── components/
            │   │   │   │   ├── ContactList/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   ├── ContactItem/
            │   │   │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   │   │   └── style.scss
            │   │   │   │   │   │   └── ContactItemPlaceholder.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── WithContacts/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── consts.ts
            │   │   │   ├── hoc/
            │   │   │   │   └── withContacts.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useContacts.ts
            │   │   │   ├── index.ts
            │   │   │   ├── query.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── contactSelector.ts
            │   │   │   ├── services/
            │   │   │   │   ├── addAddressToContact.js
            │   │   │   │   ├── form.ts
            │   │   │   │   ├── format.spec.ts
            │   │   │   │   ├── format.ts
            │   │   │   │   └── identityTypes.js
            │   │   │   ├── store/
            │   │   │   │   ├── index.ts
            │   │   │   │   ├── reducer.ts
            │   │   │   │   └── selectors.ts
            │   │   │   └── types.d.ts
            │   │   ├── control/
            │   │   │   ├── components/
            │   │   │   │   ├── ComposeButton/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ComposeContactButton/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   ├── CreateContactButton/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   └── PageActions/
            │   │   │   │       ├── action-btns.scss
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   └── index.js
            │   │   ├── device/
            │   │   │   ├── actions/
            │   │   │   │   ├── requestDevice.js
            │   │   │   │   ├── requestDevices.js
            │   │   │   │   ├── revokeDevice.js
            │   │   │   │   ├── saveDevice.js
            │   │   │   │   └── verifyDevice.js
            │   │   │   ├── hooks/
            │   │   │   │   ├── useDevice.ts
            │   │   │   │   └── useDevices.ts
            │   │   │   ├── index.ts
            │   │   │   ├── selectors.ts
            │   │   │   ├── services/
            │   │   │   │   ├── clientDevice.ts
            │   │   │   │   ├── ecdsa/
            │   │   │   │   │   └── index.ts
            │   │   │   │   ├── signature/
            │   │   │   │   │   ├── index.spec.ts
            │   │   │   │   │   └── index.ts
            │   │   │   │   ├── status.js
            │   │   │   │   └── storage/
            │   │   │   │       └── index.ts
            │   │   │   └── types.d.ts
            │   │   ├── discussion/
            │   │   │   ├── actions/
            │   │   │   │   └── requestDiscussionIdForParticipants.js
            │   │   │   ├── hooks/
            │   │   │   │   └── useDiscussion.ts
            │   │   │   ├── index.js
            │   │   │   ├── query.ts
            │   │   │   └── selectors/
            │   │   │       ├── discussionDraftSelector.js
            │   │   │       ├── discussionIdSelector.js
            │   │   │       ├── discussionSelector.js
            │   │   │       └── discussionsSelector.ts
            │   │   ├── draftIdentity/
            │   │   │   ├── hooks/
            │   │   │   │   └── useAvailableIdentities.ts
            │   │   │   └── index.ts
            │   │   ├── draftMessage/
            │   │   │   ├── actions/
            │   │   │   │   ├── consolidateParticipants.js
            │   │   │   │   ├── getDefaultIdentity.js
            │   │   │   │   ├── getDefaultIdentity.spec.js
            │   │   │   │   ├── reply.ts
            │   │   │   │   ├── requestDraft.ts
            │   │   │   │   ├── requestParticipantSuggestions.spec.ts
            │   │   │   │   ├── requestParticipantSuggestions.ts
            │   │   │   │   ├── saveDraft.ts
            │   │   │   │   └── sendDraft.ts
            │   │   │   ├── components/
            │   │   │   │   ├── AttachmentManager/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── Recipient/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── presenter.spec.jsx
            │   │   │   │   ├── RecipientList.scss
            │   │   │   │   ├── RecipientList.spec.tsx
            │   │   │   │   ├── RecipientList.tsx
            │   │   │   │   └── RecipientSelector.tsx
            │   │   │   ├── index.js
            │   │   │   ├── models.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── draft.ts
            │   │   │   ├── services/
            │   │   │   │   ├── calcSyncDraft.spec.ts
            │   │   │   │   ├── calcSyncDraft.ts
            │   │   │   │   ├── changeAuthorInParticipants.js
            │   │   │   │   ├── changeAuthorInParticipants.spec.js
            │   │   │   │   ├── filterIdentities.js
            │   │   │   │   ├── filterIdentities.spec.js
            │   │   │   │   ├── getIdentityProtocol.js
            │   │   │   │   ├── isValidRecipient.js
            │   │   │   │   ├── isValidRecipient.spec.js
            │   │   │   │   └── validate.ts
            │   │   │   └── types.d.ts
            │   │   ├── encryption/
            │   │   │   ├── actions/
            │   │   │   │   ├── decryptMessage.js
            │   │   │   │   ├── encryptMessage.js
            │   │   │   │   ├── fetchRemoteKeys.js
            │   │   │   │   └── getRecipientKeys.js
            │   │   │   ├── components/
            │   │   │   │   ├── AskPassphraseForm/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── CheckDecryption/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── LockedMessage/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   ├── message.ts
            │   │   │   │   └── publicKey.js
            │   │   │   └── services/
            │   │   │       └── keyring/
            │   │   │           └── remoteKeys.js
            │   │   ├── file/
            │   │   │   ├── actions/
            │   │   │   │   ├── deleteDraftAttachment.js
            │   │   │   │   └── uploadDraftAttachments.js
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       ├── index.js
            │   │   │       └── uploadFileAsFormField.js
            │   │   ├── form/
            │   │   │   ├── components/
            │   │   │   │   └── FormikPersist.tsx
            │   │   │   └── services/
            │   │   │       └── validators.ts
            │   │   ├── i18n/
            │   │   │   ├── components/
            │   │   │   │   └── I18nLoader.tsx
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       ├── getBestLocale.js
            │   │   │       ├── getLanguage.js
            │   │   │       └── getUserLocales.js
            │   │   ├── identity/
            │   │   │   ├── actions/
            │   │   │   │   ├── getIdentities.js
            │   │   │   │   ├── getLocalIdentities.js
            │   │   │   │   └── getRemoteIdentities.js
            │   │   │   ├── components/
            │   │   │   │   └── WithIdentities/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hoc/
            │   │   │   │   └── withIdentities.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useIdentities.ts
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   └── identitiesSelector.js
            │   │   │   ├── services/
            │   │   │   │   └── identityToParticipant.js
            │   │   │   └── types.d.ts
            │   │   ├── message/
            │   │   │   ├── actions/
            │   │   │   │   ├── createMessage.js
            │   │   │   │   ├── deleteMessage.js
            │   │   │   │   ├── fetchMessages.js
            │   │   │   │   ├── getDraft.spec.ts
            │   │   │   │   ├── getDraft.ts
            │   │   │   │   ├── getLastMessage.js
            │   │   │   │   ├── getLastMessage.spec.js
            │   │   │   │   ├── getMessage.js
            │   │   │   │   ├── getMessages.js
            │   │   │   │   ├── getParentMessage.js
            │   │   │   │   ├── requestDiscussion.js
            │   │   │   │   ├── requestMessages.js
            │   │   │   │   └── setMessageRead.js
            │   │   │   ├── components/
            │   │   │   │   └── ParticipantLabel/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useMessage.ts
            │   │   │   ├── index.js
            │   │   │   ├── models/
            │   │   │   │   ├── Message.ts
            │   │   │   │   └── Participant.ts
            │   │   │   ├── query.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── messageSelector.js
            │   │   │   ├── services/
            │   │   │   │   ├── findUserParticipant.js
            │   │   │   │   ├── findUserParticipant.spec.js
            │   │   │   │   ├── getLastMessageFromArray.js
            │   │   │   │   ├── isUserParticipant.js
            │   │   │   │   ├── isUserParticipant.spec.js
            │   │   │   │   └── sortMessages.js
            │   │   │   └── types.d.ts
            │   │   ├── notification/
            │   │   │   ├── components/
            │   │   │   │   ├── MessageNotificationHandler/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   └── NotificationProvider/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   └── messageNotificationsSelector.js
            │   │   │   └── services/
            │   │   │       └── notification.worker.js
            │   │   ├── pi/
            │   │   │   ├── components/
            │   │   │   │   ├── BackgroundImage/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── o-background-image.scss
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MultidimensionalPi/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PiGraph/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PiScore/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   └── Ratings/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.jsx
            │   │   │   ├── services/
            │   │   │   │   ├── pi/
            │   │   │   │   │   ├── index.spec.ts
            │   │   │   │   │   └── index.ts
            │   │   │   │   └── svg/
            │   │   │   │       ├── index.js
            │   │   │   │       └── index.spec.jsx
            │   │   │   └── types.d.ts
            │   │   ├── publicKey/
            │   │   │   ├── actions/
            │   │   │   │   ├── saveUserPublicKeyAction.js
            │   │   │   │   └── updatePublicKey.js
            │   │   │   └── index.js
            │   │   ├── pwa/
            │   │   │   ├── components/
            │   │   │   │   ├── InstallPromptConsumer.tsx
            │   │   │   │   └── InstallPromptProvider.tsx
            │   │   │   ├── contexts/
            │   │   │   │   └── InstallPromptContext.ts
            │   │   │   └── index.js
            │   │   ├── remoteIdentity/
            │   │   │   ├── actions/
            │   │   │   │   ├── createIdentity.js
            │   │   │   │   ├── deleteIdentity.js
            │   │   │   │   └── updateIdentity.js
            │   │   │   ├── components/
            │   │   │   │   ├── ProviderIcon/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── WithProviders/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hoc/
            │   │   │   │   ├── withAuthorize.jsx
            │   │   │   │   ├── withAuthorizePopup.jsx
            │   │   │   │   └── withProviders.jsx
            │   │   │   ├── index.js
            │   │   │   ├── model/
            │   │   │   │   └── Identity.js
            │   │   │   ├── selectors/
            │   │   │   │   ├── identitiesSelector.js
            │   │   │   │   ├── identitySelector.js
            │   │   │   │   └── identityStateSelector.js
            │   │   │   └── services/
            │   │   │       └── getProvider.js
            │   │   ├── routing/
            │   │   │   ├── components/
            │   │   │   │   ├── AuthenticatedLayout/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── withAuthenticatedProps.jsx
            │   │   │   │   ├── RoutingConsumer.jsx
            │   │   │   │   ├── RoutingProvider.jsx
            │   │   │   │   └── SwitchWithRoutes/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── index.spec.jsx
            │   │   │   ├── contexts/
            │   │   │   │   └── RoutingContext.js
            │   │   │   ├── hoc/
            │   │   │   │   ├── withPush.jsx
            │   │   │   │   ├── withReplace.jsx
            │   │   │   │   ├── withRouteParams.jsx
            │   │   │   │   └── withSearchParams.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useSearchParams.ts
            │   │   │   ├── index.js
            │   │   │   └── services/
            │   │   │       ├── findTabbableRouteConfig.js
            │   │   │       ├── flattenRouteConfig.js
            │   │   │       ├── flattenRouteConfig.spec.jsx
            │   │   │       ├── getRouterHistory.js
            │   │   │       ├── getSearchParams.spec.ts
            │   │   │       ├── getSearchParams.ts
            │   │   │       ├── signout.js
            │   │   │       └── url/
            │   │   │           ├── CrappyURLSearchParams.js
            │   │   │           ├── CrappyURLSearchParams.spec.js
            │   │   │           ├── QueryStringSerializer.js
            │   │   │           ├── buildURL.js
            │   │   │           └── index.js
            │   │   ├── scroll/
            │   │   │   ├── components/
            │   │   │   │   └── ScrollDetector/
            │   │   │   │       ├── index.js
            │   │   │   │       └── index.js.w_detection
            │   │   │   ├── hoc/
            │   │   │   │   ├── withScrollManager.jsx
            │   │   │   │   └── withScrollTarget.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useScrollToMe.ts
            │   │   │   ├── index.js
            │   │   │   ├── services/
            │   │   │   │   ├── getTop.js
            │   │   │   │   ├── getViewPortTop.js
            │   │   │   │   └── scrollTop.js
            │   │   │   └── vendors/
            │   │   │       └── scroll-doc.js
            │   │   ├── search/
            │   │   │   ├── components/
            │   │   │   │   └── SearchField/
            │   │   │   │       ├── index.js
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   └── index.js
            │   │   ├── settings/
            │   │   │   ├── components/
            │   │   │   │   └── WithSettings/
            │   │   │   │       ├── index.js
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── presenter.spec.jsx
            │   │   │   ├── hoc/
            │   │   │   │   └── withSettings.js
            │   │   │   ├── hooks/
            │   │   │   │   └── useSettings.ts
            │   │   │   ├── index.js
            │   │   │   ├── selectors/
            │   │   │   │   └── settings.ts
            │   │   │   ├── services/
            │   │   │   │   └── getDefaultSettings/
            │   │   │   │       └── index.js
            │   │   │   └── types.d.ts
            │   │   ├── tab/
            │   │   │   ├── components/
            │   │   │   │   ├── TabConsumer/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   └── TabProvider/
            │   │   │   │       └── index.jsx
            │   │   │   ├── contexts/
            │   │   │   │   └── TabContext.js
            │   │   │   ├── hoc/
            │   │   │   │   ├── withCloseTab.jsx
            │   │   │   │   ├── withCurrentTab.jsx
            │   │   │   │   └── withUpdateTab.jsx
            │   │   │   ├── hooks/
            │   │   │   │   ├── useCloseTab.ts
            │   │   │   │   └── useCurentTab.ts
            │   │   │   ├── index.js
            │   │   │   ├── model/
            │   │   │   │   └── Tab.js
            │   │   │   └── services/
            │   │   │       └── getTabUrl.js
            │   │   ├── tags/
            │   │   │   ├── components/
            │   │   │   │   ├── ManageEntityTags.spec.tsx
            │   │   │   │   ├── ManageEntityTags.tsx
            │   │   │   │   ├── TagFieldGroup/
            │   │   │   │   │   ├── index.spec.jsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── TagItem/
            │   │   │   │   │   ├── __snapshots__/
            │   │   │   │   │   │   └── index.spec.tsx.snap
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TagsForm/
            │   │   │   │       ├── index.spec.tsx
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── hoc/
            │   │   │   │   └── withTags/
            │   │   │   │       └── index.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useTags.ts
            │   │   │   ├── index.ts
            │   │   │   ├── query.ts
            │   │   │   ├── services/
            │   │   │   │   ├── getTagLabel/
            │   │   │   │   │   ├── index.spec.ts
            │   │   │   │   │   └── index.ts
            │   │   │   │   ├── getTagNamesInCommon.spec.ts
            │   │   │   │   ├── getTagNamesInCommon.ts
            │   │   │   │   ├── searchTags.spec.ts
            │   │   │   │   └── searchTags.ts
            │   │   │   ├── store/
            │   │   │   │   ├── index.ts
            │   │   │   │   ├── reducer.ts
            │   │   │   │   └── selectors.ts
            │   │   │   └── types.d.ts
            │   │   ├── user/
            │   │   │   ├── actions/
            │   │   │   │   └── getUser.js
            │   │   │   ├── components/
            │   │   │   │   ├── SigninForm/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   └── SubmitButton.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── SignupForm/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   └── PiwikModal.tsx
            │   │   │   │   │   ├── form-validator.spec.ts
            │   │   │   │   │   ├── form-validator.ts
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── UserInfo/
            │   │   │   │   │   ├── UserInfo.spec.tsx
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── UserMenu/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── next-feature-button.scss
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   ├── presenter.spec.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── WithUser/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── hoc/
            │   │   │   │   └── withUser.jsx
            │   │   │   ├── hooks/
            │   │   │   │   └── useUser.ts
            │   │   │   ├── index.ts
            │   │   │   ├── selectors/
            │   │   │   │   └── userSelector.ts
            │   │   │   ├── services/
            │   │   │   │   ├── deleteUser.js
            │   │   │   │   ├── isAuthenticated/
            │   │   │   │   │   └── index.js
            │   │   │   │   ├── signup/
            │   │   │   │   │   └── index.js
            │   │   │   │   └── usernameNormalizer/
            │   │   │   │       └── index.js
            │   │   │   ├── store/
            │   │   │   │   ├── index.ts
            │   │   │   │   ├── reducer.ts
            │   │   │   │   └── selectors.ts
            │   │   │   └── types.d.ts
            │   │   ├── userNotify/
            │   │   │   ├── actions/
            │   │   │   │   └── notify.js
            │   │   │   ├── hoc/
            │   │   │   │   └── withNotification.jsx
            │   │   │   └── index.js
            │   │   └── view/
            │   │       ├── actions/
            │   │       │   └── requestMessages.js
            │   │       ├── components/
            │   │       │   └── WithViewModel/
            │   │       │       └── index.jsx
            │   │       ├── config.js
            │   │       ├── index.js
            │   │       ├── models/
            │   │       │   └── View.js
            │   │       └── selectors/
            │   │           └── viewSelector.js
            │   ├── scenes/
            │   │   ├── About/
            │   │   │   ├── components/
            │   │   │   │   └── StylezedScreenshot/
            │   │   │   │       └── index.tsx
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── ApplicationSettings/
            │   │   │   ├── components/
            │   │   │   │   ├── ContactSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   ├── DesktopNotificationSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── InterfaceSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   ├── MessageSettings/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   └── presenter.jsx
            │   │   │   │   └── NotificationSettings/
            │   │   │   │       ├── index.js
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── ContactAssociation/
            │   │   │   ├── contact-association.scss
            │   │   │   ├── index.spec.tsx
            │   │   │   └── index.tsx
            │   │   ├── DevicesSettings/
            │   │   │   ├── components/
            │   │   │   │   ├── DeviceForm/
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── DeviceInformation/
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── DeviceSettings/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── RevokeDevice/
            │   │   │   │   │   ├── index.spec.tsx
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── VerifyDevice/
            │   │   │   │       ├── index.spec.tsx
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Discussion/
            │   │   │   ├── components/
            │   │   │   │   ├── AddParticipantsToContactBook/
            │   │   │   │   │   ├── add-participants-dropdown.scss
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── DownloadFileProgression/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── InstantMessage/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   ├── instant-message-aside.scss
            │   │   │   │   │   ├── instant-message-author.scss
            │   │   │   │   │   ├── instant-message-participants.scss
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MailMessage/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   ├── mail-message-details.scss
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── Message.tsx
            │   │   │   │   ├── MessageAttachments/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MessageList/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MessagePi/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── MessageRecipients.tsx
            │   │   │   │   ├── ProtocolSwitch/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── QuickDraftForm/
            │   │   │   │   │   ├── components/
            │   │   │   │   │   │   └── ToggleAdvancedFormButton/
            │   │   │   │   │   │       ├── index.jsx
            │   │   │   │   │   │       └── toggle-advanced-draft-button.scss
            │   │   │   │   │   ├── draft-message-quick.scss
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── ReplyExcerpt/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TagList/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── discussion-action-bar.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   ├── style.scss
            │   │   │   └── types.d.ts
            │   │   ├── ForgotPassword/
            │   │   │   ├── components/
            │   │   │   │   └── ForgotPasswordForm/
            │   │   │   │       ├── index.jsx
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── presenter.spec.jsx
            │   │   ├── NewDeviceInfo/
            │   │   │   ├── index.jsx
            │   │   │   └── style.scss
            │   │   ├── NewDraft/
            │   │   │   ├── components/
            │   │   │   │   ├── DraftDiscussion/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── useDraftDiscussion.tsx
            │   │   │   │   └── DraftMessage/
            │   │   │   │       ├── components/
            │   │   │   │       │   ├── IdentitySelector.tsx
            │   │   │   │       │   └── Recipients.tsx
            │   │   │   │       ├── draft-message-advanced.scss
            │   │   │   │       ├── draft-message-placeholder.scss
            │   │   │   │       └── index.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── RemoteIdentitySettings/
            │   │   │   ├── components/
            │   │   │   │   ├── AuthButton/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── LastConnection/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── NewIdentity/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── new-identity.scss
            │   │   │   │   │   ├── provider-email-button.scss
            │   │   │   │   │   └── provider-list.scss
            │   │   │   │   ├── ProviderButton/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ProviderButtonContainer/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── RemoteIdentity/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   ├── RemoteIdentityDetails/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── RemoteIdentityEmail/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── index.spec.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── RemoteIdentityOauth/
            │   │   │   │   │   └── index.jsx
            │   │   │   │   └── Status/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── ResetPassword/
            │   │   │   ├── components/
            │   │   │   │   └── ResetPasswordForm/
            │   │   │   │       ├── index.jsx
            │   │   │   │       ├── presenter.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── presenter.spec.jsx
            │   │   ├── SearchResults/
            │   │   │   ├── components/
            │   │   │   │   ├── ContactResultItem/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── Highlights/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   ├── index.spec.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── MessageResultItem/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── SettingsSignatures/
            │   │   │   ├── components/
            │   │   │   │   └── SignatureForm/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── presenter.jsx
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── Signin.tsx
            │   │   ├── Signup.tsx
            │   │   ├── TagsSettings/
            │   │   │   ├── components/
            │   │   │   │   ├── TagInput/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TagSearch/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── Timeline/
            │   │   │   ├── components/
            │   │   │   │   ├── DiscussionItem/
            │   │   │   │   │   ├── discussion-item-content.scss
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── DiscussionSelector/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   ├── style.scss
            │   │   │   └── timeline-action-bar.scss
            │   │   ├── UserPrivacy/
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── UserProfile/
            │   │   │   ├── components/
            │   │   │   │   ├── ProfileForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── ProfileInfo/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.spec.tsx
            │   │   │   ├── index.tsx
            │   │   │   └── style.scss
            │   │   ├── UserSecurity/
            │   │   │   ├── components/
            │   │   │   │   ├── LoginDetails/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── OpenPGPForm.scss
            │   │   │   │   ├── OpenPGPGenerateForm.tsx
            │   │   │   │   ├── OpenPGPImportForm.tsx
            │   │   │   │   ├── OpenPGPKey/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── OpenPGPPrivateKeys/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PasswordDetails/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PasswordForm/
            │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── TFAForm/
            │   │   │   │       └── index.jsx
            │   │   │   ├── index.jsx
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── ValidateDevice/
            │   │   │   ├── index.js
            │   │   │   ├── presenter.jsx
            │   │   │   └── style.scss
            │   │   ├── View/
            │   │   │   ├── components/
            │   │   │   │   ├── MessageItem/
            │   │   │   │   │   ├── index.js
            │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── MessageSelector/
            │   │   │   │       ├── index.jsx
            │   │   │   │       └── style.scss
            │   │   │   ├── index.jsx
            │   │   │   ├── style.scss
            │   │   │   └── withCurrentView.jsx
            │   │   ├── contact/
            │   │   │   ├── Contact.tsx
            │   │   │   ├── ContactBook/
            │   │   │   │   ├── components/
            │   │   │   │   │   ├── ImportContact/
            │   │   │   │   │   │   ├── index.js
            │   │   │   │   │   │   └── presenter.jsx
            │   │   │   │   │   ├── ImportContactButton/
            │   │   │   │   │   │   └── index.tsx
            │   │   │   │   │   ├── ImportContactForm/
            │   │   │   │   │   │   ├── index.jsx
            │   │   │   │   │   │   ├── presenter.jsx
            │   │   │   │   │   │   └── style.scss
            │   │   │   │   │   └── TagList/
            │   │   │   │   │       ├── index.tsx
            │   │   │   │   │       └── style.scss
            │   │   │   │   ├── contact-book-menu.scss
            │   │   │   │   ├── index.spec.tsx
            │   │   │   │   ├── index.tsx
            │   │   │   │   ├── query.spec.tsx
            │   │   │   │   ├── query.ts
            │   │   │   │   └── style.scss
            │   │   │   ├── ContactForm.tsx
            │   │   │   ├── EditContact.spec.tsx
            │   │   │   ├── EditContact.tsx
            │   │   │   ├── NewContact.spec.tsx
            │   │   │   ├── NewContact.tsx
            │   │   │   ├── components/
            │   │   │   │   ├── AddFormFieldForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── AddressDetails/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── AddressForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── BirthdayDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── BirthdayForm/
            │   │   │   │   │   ├── index.ts
            │   │   │   │   │   └── presenter.tsx
            │   │   │   │   ├── ContactPageWrapper.tsx
            │   │   │   │   ├── ContactProfileForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ContactTitleField/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── EmailDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── EmailForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── FormCollection/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── IdentityDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── IdentityForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── ImDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── ImForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── OrgaDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── OrgaForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PhoneDetails/
            │   │   │   │   │   └── index.tsx
            │   │   │   │   ├── PhoneForm/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PublicKeyForm/
            │   │   │   │   │   ├── index.ts
            │   │   │   │   │   ├── presenter.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   ├── PublicKeyList/
            │   │   │   │   │   ├── index.tsx
            │   │   │   │   │   └── style.scss
            │   │   │   │   └── ReduxedInputFileGroup/
            │   │   │   │       ├── index.tsx
            │   │   │   │       └── style.scss
            │   │   │   ├── contact-action-bar.scss
            │   │   │   ├── contact-main-title.scss
            │   │   │   ├── services/
            │   │   │   │   ├── contactValidation.jsx
            │   │   │   │   ├── contactValidation.spec.jsx
            │   │   │   │   ├── handleContactSaveErrors.spec.ts
            │   │   │   │   └── handleContactSaveErrors.ts
            │   │   │   └── style.scss
            │   │   └── error/
            │   │       ├── PageError.tsx
            │   │       ├── PageNotFound.tsx
            │   │       ├── components/
            │   │       │   └── CaliopenAscii.tsx
            │   │       └── style.scss
            │   ├── services/
            │   │   ├── api-client/
            │   │   │   ├── index.ts
            │   │   │   └── types.d.ts
            │   │   ├── api-location/
            │   │   │   └── index.js
            │   │   ├── api-patch/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── asciify.js
            │   │   ├── asciify.spec.js
            │   │   ├── browser-notification/
            │   │   │   └── index.js
            │   │   ├── capitalize.js
            │   │   ├── config.ts
            │   │   ├── encode-utils/
            │   │   │   ├── index.js
            │   │   │   └── utf8ArrayToString.js
            │   │   ├── encryption/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── event-manager/
            │   │   │   └── index.js
            │   │   ├── filter-contacts/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── importance-level/
            │   │   │   └── index.js
            │   │   ├── localStorage/
            │   │   │   └── index.js
            │   │   ├── message/
            │   │   │   ├── index.js
            │   │   │   └── index.spec.js
            │   │   ├── mime/
            │   │   │   └── index.js
            │   │   ├── openpgp-keychain-repository/
            │   │   │   └── index.js
            │   │   ├── openpgp-manager/
            │   │   │   ├── api.ts
            │   │   │   ├── errors.ts
            │   │   │   ├── index.spec.ts
            │   │   │   └── index.ts
            │   │   ├── protocols-config/
            │   │   │   └── index.ts
            │   │   ├── renderReduxField/
            │   │   │   └── index.jsx
            │   │   └── username-utils/
            │   │       ├── username-availability.ts
            │   │       ├── username-validity.spec.ts
            │   │       └── username-validity.ts
            │   ├── store/
            │   │   ├── actions/
            │   │   │   ├── message.js
            │   │   │   └── timeline.js
            │   │   ├── configure-store.ts
            │   │   ├── middlewares/
            │   │   │   ├── axios-middleware.ts
            │   │   │   ├── crash-reporter-middleware.js
            │   │   │   ├── decryption-middleware.js
            │   │   │   ├── discussions-middleware.js
            │   │   │   ├── encryption-middleware.js
            │   │   │   ├── freeze.js
            │   │   │   ├── importance-level-middleware.js
            │   │   │   ├── messages-middleware.js
            │   │   │   └── search-middleware.js
            │   │   ├── modules/
            │   │   │   ├── device.ts
            │   │   │   ├── discussion.ts
            │   │   │   ├── draft-message.spec.ts
            │   │   │   ├── draft-message.ts
            │   │   │   ├── encryption.ts
            │   │   │   ├── i18n.js
            │   │   │   ├── importance-level.js
            │   │   │   ├── local-identity.js
            │   │   │   ├── message.js
            │   │   │   ├── message.spec.js
            │   │   │   ├── notification.js
            │   │   │   ├── participant-suggestions.ts
            │   │   │   ├── provider.js
            │   │   │   ├── public-key.js
            │   │   │   ├── remote-identity.js
            │   │   │   ├── search.js
            │   │   │   ├── settings.js
            │   │   │   └── view.js
            │   │   ├── reducer.ts
            │   │   └── selectors/
            │   │       ├── device.js
            │   │       ├── getModuleStateSelector.js
            │   │       ├── message.js
            │   │       ├── provider.js
            │   │       ├── settings.js
            │   │       ├── tab.js
            │   │       └── timeline.js
            │   ├── styles/
            │   │   ├── base/
            │   │   │   ├── fonts.scss
            │   │   │   └── reset.scss
            │   │   ├── common.scss
            │   │   ├── config/
            │   │   │   ├── config.scss
            │   │   │   └── theme/
            │   │   │       ├── dark.scss
            │   │   │       └── light.scss
            │   │   ├── object/
            │   │   │   ├── o-avatar.scss
            │   │   │   ├── o-callout.scss
            │   │   │   ├── o-clickable.scss
            │   │   │   ├── o-date-picker.scss
            │   │   │   ├── o-form-element.scss
            │   │   │   ├── o-hidden-element.scss
            │   │   │   ├── o-navigation.scss
            │   │   │   ├── o-pi-border.scss
            │   │   │   ├── o-reset-html-message.scss
            │   │   │   └── o-triangle.scss
            │   │   ├── util/
            │   │   │   ├── breakpoint.scss
            │   │   │   ├── flex-grid.scss
            │   │   │   └── u-gradient.scss
            │   │   └── vendor/
            │   │       ├── bootstrap_font-awesome.scss
            │   │       ├── bootstrap_foundation-sites.scss
            │   │       ├── bootstrap_react-redux-notify.scss
            │   │       └── foundation-sites/
            │   │           ├── _config.scss
            │   │           └── _flex-grid.scss
            │   └── types.d.ts
            ├── template/
            │   ├── index.ejs
            │   └── index.html
            ├── test/
            │   ├── fixtures/
            │   │   ├── contacts/
            │   │   │   ├── data.json
            │   │   │   └── index.ts
            │   │   ├── device/
            │   │   │   └── index.ts
            │   │   ├── tags/
            │   │   │   └── data.json
            │   │   └── user/
            │   │       ├── data.json
            │   │       └── index.ts
            │   ├── functional/
            │   │   ├── features/
            │   │   │   ├── 00_home-spec.js
            │   │   │   ├── 10_discussion-spec.js
            │   │   │   ├── 20-message-list-spec.js
            │   │   │   ├── 21-reply-to-messag-spec.js
            │   │   │   ├── 22-compose-spec.js
            │   │   │   ├── 23-delete-message-spec.js
            │   │   │   ├── 24-scroll-spec.js
            │   │   │   ├── 25-assoc-participant-contact-spec.js
            │   │   │   ├── 30-settings-spec.js
            │   │   │   ├── 35-remote-identitiy-settings-spec.js
            │   │   │   ├── 40-new-contact-spec.js
            │   │   │   ├── 50-search-spec.js
            │   │   │   ├── 60-tag-spec.js
            │   │   │   ├── 70-device-spec.js
            │   │   │   ├── 80-account-spec.js
            │   │   │   └── 90_notification-spec.js
            │   │   ├── protractor.conf.js
            │   │   └── utils/
            │   │       ├── navigation.js
            │   │       ├── timeline.js
            │   │       ├── user-util.js
            │   │       └── window.js
            │   ├── msw-handlers/
            │   │   ├── contacts.ts
            │   │   ├── settings.ts
            │   │   ├── tags.ts
            │   │   └── user.ts
            │   ├── providers.tsx
            │   ├── server.ts
            │   └── unit/
            │       ├── lingui-react.jsx
            │       └── setup.ts
            ├── tsconfig.json
            └── webpack/
                ├── config.js
                ├── webpack.common.js
                ├── webpack.config.browser.js
                └── webpack.config.server.js
Download .txt
Showing preview only (421K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4599 symbols across 846 files)

FILE: devtools/extract/email_graph.py
  function valid_uuid (line 17) | def valid_uuid(uuid):
  function anonymise_email (line 25) | def anonymise_email(email):
  class EmailGraph (line 35) | class EmailGraph(ESProvider):
    method _format_item (line 37) | def _format_item(self, message):
  class Extractor (line 66) | class Extractor(object):
    method __init__ (line 68) | def __init__(self, config):
    method _get_indices (line 72) | def _get_indices(self):
    method process (line 77) | def process(self, output, index=None):

FILE: devtools/migrations/index_migration_v0_to_v2.py
  class IndexMigrator (line 10) | class IndexMigrator(object):
    method __init__ (line 11) | def __init__(self, es_client):
    method run (line 15) | def run(self):
    method create_new_index (line 47) | def create_new_index(self, index):
    method copy_old_to_new (line 97) | def copy_old_to_new(self, old, new):
    method delete_old_index (line 114) | def delete_old_index(self, index):
    method create_alias (line 123) | def create_alias(self, alias, index):

FILE: devtools/migrations/index_migration_v2_to_v3.py
  class IndexMigrator (line 14) | class IndexMigrator(object):
    method __init__ (line 15) | def __init__(self, client=None, mappings_version=None):
    method check_empty_index (line 20) | def check_empty_index(self, index):
    method run (line 34) | def run(self):
    method create_new_index (line 80) | def create_new_index(self, index):
    method copy_old_to_new (line 134) | def copy_old_to_new(self, old, new):
    method delete_old_index (line 151) | def delete_old_index(self, index):
    method move_alias (line 160) | def move_alias(self, alias, old_index, new_index):

FILE: devtools/migrations/index_migration_v3_to_v4.py
  class IndexMigrator (line 14) | class IndexMigrator(object):
    method __init__ (line 15) | def __init__(self, client=None, mappings_version=None):
    method check_empty_index (line 20) | def check_empty_index(self, index):
    method run (line 34) | def run(self):
    method create_new_index (line 80) | def create_new_index(self, index):
    method copy_old_to_new (line 134) | def copy_old_to_new(self, old, new):
    method delete_old_index (line 151) | def delete_old_index(self, index):
    method move_alias (line 160) | def move_alias(self, alias, old_index, new_index):

FILE: devtools/migrations/index_migration_v4_to_v5.py
  class IndexMigrator (line 16) | class IndexMigrator(object):
    method __init__ (line 17) | def __init__(self, client=None, mappings_version=None, url=None):
    method check_empty_index (line 23) | def check_empty_index(self, index):
    method run (line 37) | def run(self):
    method create_new_index (line 87) | def create_new_index(self, index):
    method copy_old_to_new (line 141) | def copy_old_to_new(self, old, new):
    method delete_old_index (line 158) | def delete_old_index(self, index):
    method move_alias (line 167) | def move_alias(self, alias, old_index, new_index):
    method fill_date_sort (line 178) | def fill_date_sort(self, index):

FILE: devtools/migrations/index_migration_v5_to_v6.py
  class IndexMigrator (line 14) | class IndexMigrator(object):
    method __init__ (line 15) | def __init__(self, client=None, mappings_version=None, url=None):
    method check_empty_index (line 21) | def check_empty_index(self, index):
    method run (line 35) | def run(self):
    method create_new_index (line 84) | def create_new_index(self, index):
    method copy_old_to_new (line 138) | def copy_old_to_new(self, old, new):
    method delete_old_index (line 155) | def delete_old_index(self, index):
    method move_alias (line 164) | def move_alias(self, alias, old_index, new_index):

FILE: devtools/storybook/.storybook/config.js
  function loadStories (line 6) | function loadStories() {

FILE: devtools/storybook/stories/Welcome.jsx
  class Welcome (line 33) | class Welcome extends React.Component {
    method showApp (line 34) | showApp(e) {
    method render (line 39) | render() {

FILE: devtools/storybook/stories/components/BlockList.jsx
  class BlockLists (line 7) | class BlockLists extends Component {
    method render (line 8) | render() {

FILE: devtools/storybook/stories/components/FormGrid.jsx
  class Presenter (line 36) | class Presenter extends Component {
    method render (line 37) | render() {

FILE: devtools/storybook/stories/components/MessageList.jsx
  class Presenter (line 6) | class Presenter extends Component {
    method constructor (line 7) | constructor(props) {
    method handleInputChange (line 17) | handleInputChange(event) {
    method render (line 28) | render() {

FILE: devtools/storybook/stories/components/Reply.jsx
  class Presenter (line 7) | class Presenter extends Component {
    method constructor (line 8) | constructor(props) {
    method handleInputChange (line 18) | handleInputChange(event) {
    method render (line 29) | render() {

FILE: devtools/storybook/stories/layouts/ContactBook.jsx
  class Presenter (line 6) | class Presenter extends Component {
    method constructor (line 7) | constructor(props) {
    method handlePropsChanges (line 17) | handlePropsChanges(event) {
    method render (line 29) | render() {

FILE: devtools/storybook/stories/layouts/Devices.jsx
  class Presenter (line 7) | class Presenter extends Component {
    method constructor (line 8) | constructor(props) {
    method render (line 17) | render() {

FILE: devtools/storybook/stories/layouts/SigninPage.jsx
  class Presenter (line 7) | class Presenter extends Component {
    method render (line 8) | render() {

FILE: devtools/storybook/stories/layouts/SignupPage.jsx
  class Presenter (line 7) | class Presenter extends Component {
    method render (line 8) | render() {

FILE: src/backend/brokers/go.emails/broker.go
  type EmailBroker (line 23) | type EmailBroker struct
    method ShutDown (line 195) | func (broker *EmailBroker) ShutDown() {
  type EmailBrokerConnectors (line 33) | type EmailBrokerConnectors struct
  type SmtpEmail (line 38) | type SmtpEmail struct
  type natsOrder (line 45) | type natsOrder struct
  type MTAparams (line 52) | type MTAparams struct
  type EmailDeliveryAck (line 60) | type EmailDeliveryAck struct
  function Initialize (line 71) | func Initialize(conf LDAConfig) (broker *EmailBroker, connectors EmailBr...

FILE: src/backend/brokers/go.emails/email.go
  function newAddressesFields (line 30) | func newAddressesFields() (af map[string][]string) {
  method NewMessageId (line 43) | func (b *EmailBroker) NewMessageId(uuid []byte) string {
  method MarshalEmail (line 56) | func (b *EmailBroker) MarshalEmail(msg *Message) (em *EmailMessage, err ...
  method SaveIndexSentEmail (line 179) | func (b *EmailBroker) SaveIndexSentEmail(ack *EmailDeliveryAck) error {
  method UnmarshalEmail (line 281) | func (b *EmailBroker) UnmarshalEmail(em *EmailMessage, user_id UUID) (ms...
  method unmarshalParticipants (line 328) | func (b *EmailBroker) unmarshalParticipants(h mail.Header, address_type ...
  function EmailToJsonRep (line 362) | func EmailToJsonRep(email string) (json_email EmailJson, err error) {
  function addPart (line 432) | func addPart(parent []Part, part enmime.MIMEPart, isChild bool) []Part {
  function GetBoundary (line 485) | func GetBoundary(s string) (boundary string, err error) {

FILE: src/backend/brokers/go.emails/encrypt.go
  function randomString (line 20) | func randomString(n int) string {
  method NewBoundary (line 34) | func (b *EmailBroker) NewBoundary() string {
  method MarshalPGPEmail (line 39) | func (b *EmailBroker) MarshalPGPEmail(msg *Message, em *EmailMessage, ad...
  function formatBody (line 70) | func formatBody(msg *Message, mainHeader message.Header) (bytes.Buffer, ...

FILE: src/backend/brokers/go.emails/inbound.go
  constant natsMessageTmpl (line 28) | natsMessageTmpl = "{\"order\":\"%s\",\"user_id\":\"%s\",\"identity_id\":...
  constant natsOrderRaw (line 29) | natsOrderRaw    = "process_raw"
  method startIncomingSmtpAgents (line 32) | func (b *EmailBroker) startIncomingSmtpAgents() error {
  method incomingSmtpWorker (line 40) | func (b *EmailBroker) incomingSmtpWorker() {
  method startImapAgents (line 56) | func (b *EmailBroker) startImapAgents() error {
  method imapWorker (line 64) | func (b *EmailBroker) imapWorker() {
  method processInboundSMTP (line 80) | func (b *EmailBroker) processInboundSMTP(in *SmtpEmail, raw_only bool) {
  method processInboundIMAP (line 121) | func (b *EmailBroker) processInboundIMAP(in *SmtpEmail) {
  method processInbound (line 145) | func (b *EmailBroker) processInbound(rcptsIds [][]UUID, in *SmtpEmail, r...
  method deliverMsgToUser (line 259) | func (b *EmailBroker) deliverMsgToUser() {}
  function ListFormatFunc (line 263) | func ListFormatFunc(es []error) string {

FILE: src/backend/brokers/go.emails/outbound.go
  method startOutcomingSmtpAgents (line 29) | func (b *EmailBroker) startOutcomingSmtpAgents() error {
  method natsMsgHandler (line 50) | func (b *EmailBroker) natsMsgHandler(msg *nats.Msg) (resp []byte, err er...
  method natsReplyError (line 186) | func (b *EmailBroker) natsReplyError(msg *nats.Msg, err error) {

FILE: src/backend/brokers/go.mastodon/broker.go
  type MastodonBroker (line 17) | type MastodonBroker struct
    method ShutDown (line 79) | func (broker *MastodonBroker) ShutDown() {
  type BrokerConfig (line 27) | type BrokerConfig struct
  type MastodonBrokerConnectors (line 40) | type MastodonBrokerConnectors struct
  type DMpayload (line 45) | type DMpayload struct
  type MastodonDeliveryAck (line 52) | type MastodonDeliveryAck struct
  type NatsCom (line 59) | type NatsCom struct
  function Initialize (line 65) | func Initialize(conf BrokerConfig, store backends.LDAStore, index backen...

FILE: src/backend/brokers/go.mastodon/direct_messages.go
  method SaveRawDM (line 20) | func (broker *MastodonBroker) SaveRawDM(dm *mastodon.Status, userId UUID...
  method SaveIndexSentDM (line 44) | func (b *MastodonBroker) SaveIndexSentDM(initialOrder BrokerOrder, ack *...
  function UnmarshalDM (line 97) | func UnmarshalDM(dm *mastodon.Status, userId UUID) (message *Message, er...
  function MarshalDM (line 102) | func MarshalDM(msg *Message) (toot *mastodon.Toot, err error) {
  function IDgreaterOrEqual (line 120) | func IDgreaterOrEqual(first, second string) bool {

FILE: src/backend/brokers/go.mastodon/inbound.go
  constant natsMessageTmpl (line 20) | natsMessageTmpl  = "{\"order\":\"%s\",\"user_id\":\"%s\",\"identity_id\"...
  constant natsOrderRaw (line 21) | natsOrderRaw     = "process_raw"
  constant NatsError (line 22) | NatsError        = "nats error"
  constant lastSeenInfosKey (line 23) | lastSeenInfosKey = "lastseendm"
  constant lastSyncInfosKey (line 24) | lastSyncInfosKey = "lastsync"
  method ProcessInDM (line 32) | func (broker *MastodonBroker) ProcessInDM(userID, remoteID UUID, dm *mas...

FILE: src/backend/brokers/go.mastodon/outbound.go
  method ProcessOutDM (line 17) | func (b *MastodonBroker) ProcessOutDM(order BrokerOrder, worker chan *DM...
  function replyError (line 72) | func replyError(err error, worker chan *DMpayload) {

FILE: src/backend/brokers/go.twitter/broker.go
  type TwitterBroker (line 19) | type TwitterBroker struct
    method ShutDown (line 81) | func (broker *TwitterBroker) ShutDown() {
  type BrokerConfig (line 29) | type BrokerConfig struct
  type TwitterBrokerConnectors (line 42) | type TwitterBrokerConnectors struct
  type DMpayload (line 47) | type DMpayload struct
  type TwitterDeliveryAck (line 54) | type TwitterDeliveryAck struct
  type NatsCom (line 61) | type NatsCom struct
  function Initialize (line 67) | func Initialize(conf BrokerConfig, store backends.LDAStore, index backen...

FILE: src/backend/brokers/go.twitter/direct_messages.go
  constant DirectMessageType (line 21) | DirectMessageType = "message_create"
  method SaveRawDM (line 25) | func (broker *TwitterBroker) SaveRawDM(dm *twitter.DirectMessageEvent, u...
  method SaveIndexSentDM (line 51) | func (b *TwitterBroker) SaveIndexSentDM(initialOrder BrokerOrder, ack *T...
  function UnmarshalDM (line 109) | func UnmarshalDM(dm *twitter.DirectMessageEvent, userId UUID) (message *...
  function MarshalDM (line 114) | func MarshalDM(msg *Message) (dm *twitter.DirectMessageEvent, err error) {

FILE: src/backend/brokers/go.twitter/inbound.go
  constant natsMessageTmpl (line 22) | natsMessageTmpl  = "{\"order\":\"%s\",\"user_id\":\"%s\",\"identity_id\"...
  constant natsOrderRaw (line 23) | natsOrderRaw     = "process_raw"
  constant NatsError (line 24) | NatsError        = "nats error"
  constant lastSeenInfosKey (line 25) | lastSeenInfosKey = "lastseendm"
  constant lastSyncInfosKey (line 26) | lastSyncInfosKey = "lastsync"
  method ProcessInDM (line 34) | func (broker *TwitterBroker) ProcessInDM(userID, remoteID UUID, dm *twit...

FILE: src/backend/brokers/go.twitter/outbound.go
  method ProcessOutDM (line 25) | func (b *TwitterBroker) ProcessOutDM(order BrokerOrder, worker chan *DMp...
  function replyError (line 84) | func replyError(err error, worker chan *DMpayload) {

FILE: src/backend/components/py.data/caliopen_data/interface.py
  class IDataProvider (line 12) | class IDataProvider(zope.interface.Interface):
    method _connect_store (line 15) | def _connect_store(self):
    method _format_item (line 18) | def _format_item(self, item):
    method _prepare (line 22) | def _prepare(self, query, **kwargs):
    method _execute (line 25) | def _execute(self, **kwargs):
    method next (line 28) | def next(self):

FILE: src/backend/components/py.data/caliopen_data/provider.py
  class DataProvider (line 13) | class DataProvider(object):
    method __init__ (line 16) | def __init__(self, config):
    method prepare (line 23) | def prepare(self, query, **kwargs):
    method next (line 28) | def next(self):
  class FileDataProvider (line 36) | class FileDataProvider(DataProvider):
    method __init__ (line 41) | def __init__(self, config):
    method _connect_store (line 46) | def _connect_store(self):
    method _prepare (line 49) | def _prepare(self, filename, **kwargs):
    method _execute (line 54) | def _execute(self):
  class ESProvider (line 61) | class ESProvider(DataProvider):
    method _connect_store (line 66) | def _connect_store(self):
    method _prepare (line 70) | def _prepare(self, query, index=None, doc_type=None, **kwargs):
    method _execute (line 75) | def _execute(self, **kwargs):

FILE: src/backend/components/py.data/caliopen_data/store.py
  function save_file (line 11) | def save_file(config, input_file, dest):

FILE: src/backend/components/py.pgp/caliopen_pgp/keys/base.py
  class PGPUserId (line 13) | class PGPUserId(object):
    method __init__ (line 16) | def __init__(self, name, email, is_primary, comment=None, signers=None):
  class PGPPublicKey (line 24) | class PGPPublicKey(object):
    method __init__ (line 39) | def __init__(self, keyid, public_key):
    method _get_userids (line 65) | def _get_userids(self, ids):
    method armored_key (line 71) | def armored_key(self):
  class DiscoveryResult (line 76) | class DiscoveryResult(object):
    method __init__ (line 79) | def __init__(self, keys, extra_identities=None):
    method emails (line 84) | def emails(self):
  class BaseDiscovery (line 94) | class BaseDiscovery(object):
    method empty_result (line 98) | def empty_result(self):
    method lookup_identity (line 102) | def lookup_identity(self, identity, type_):
    method _parse_key (line 106) | def _parse_key(self, armored):

FILE: src/backend/components/py.pgp/caliopen_pgp/keys/contact.py
  class ContactDiscoveryResult (line 13) | class ContactDiscoveryResult(object):
    method __init__ (line 16) | def __init__(self):
  class ContactPublicKeyManager (line 23) | class ContactPublicKeyManager(object):
    method __init__ (line 26) | def __init__(self):
    method _find_keys (line 31) | def _find_keys(self, user, contact, new_identifier, type_):
    method _filter_new_emails (line 45) | def _filter_new_emails(self, contact, key):
    method _filter_new_identities (line 53) | def _filter_new_identities(self, contact, identities):
    method process_identity (line 60) | def process_identity(self, user, contact, new_identifier, type_):

FILE: src/backend/components/py.pgp/caliopen_pgp/keys/discoverer.py
  class PublicKeyDiscoverer (line 16) | class PublicKeyDiscoverer(object):
    method __init__ (line 21) | def __init__(self, conf):
    method lookup_identity (line 35) | def lookup_identity(self, identity, type_):

FILE: src/backend/components/py.pgp/caliopen_pgp/keys/hkp.py
  function check_version (line 20) | def check_version(record):
  function parse_date (line 25) | def parse_date(date):
  function parse_pubkey_record (line 29) | def parse_pubkey_record(record):
  function parse_uid_record (line 34) | def parse_uid_record(record):
  function parse_search_result (line 38) | def parse_search_result(lines):
  class HKPDiscovery (line 53) | class HKPDiscovery(BaseDiscovery):
    method __init__ (line 60) | def __init__(self, conf):
    method lookup_identity (line 64) | def lookup_identity(self, identity, type_):
    method _search_keys (line 77) | def _search_keys(self, email):
    method _search_key (line 96) | def _search_key(self, keyid):

FILE: src/backend/components/py.pgp/caliopen_pgp/keys/keybase.py
  class KeybaseDiscovery (line 13) | class KeybaseDiscovery(BaseDiscovery):
    method __init__ (line 23) | def __init__(self, conf):
    method lookup_identity (line 29) | def lookup_identity(self, identifier, type_):
    method _clean_name (line 52) | def _clean_name(self, name, type_):
    method _fetch_identity (line 59) | def _fetch_identity(self, name, type_):
    method _get_public_key (line 81) | def _get_public_key(self, username):

FILE: src/backend/components/py.pgp/caliopen_pgp/keys/rfc7929.py
  function compute_qname (line 23) | def compute_qname(username, domain):
  class DNSDiscovery (line 30) | class DNSDiscovery(BaseDiscovery):
    method __init__ (line 35) | def __init__(self, conf):
    method lookup_identity (line 39) | def lookup_identity(self, identity, type_):
    method _extract_key (line 67) | def _extract_key(self, record):

FILE: src/backend/components/py.pi/caliopen_pi/features/contact.py
  function pstdev (line 17) | def pstdev(avg, data):
  class ContactFeature (line 23) | class ContactFeature(object):
    method __init__ (line 26) | def __init__(self, user, conf=None):
    method _compute_histogram (line 31) | def _compute_histogram(self, email):
    method _get_histogram (line 43) | def _get_histogram(self, contact):
    method _get_technical (line 54) | def _get_technical(self, contact):
    method _compute_pi (line 63) | def _compute_pi(self, contact, features):
    method process (line 94) | def process(self, contact):

FILE: src/backend/components/py.pi/caliopen_pi/features/device.py
  class Singleton (line 16) | class Singleton(object):
    method __new__ (line 21) | def __new__(cls, *args, **kwargs):
  class GeoipReader (line 28) | class GeoipReader(Singleton):
    method __init__ (line 31) | def __init__(self, filename):
  class DeviceFeature (line 36) | class DeviceFeature(object):
    method __init__ (line 39) | def __init__(self, user, conf=None):
    method process (line 45) | def process(self, device):
    method _get_device_type (line 64) | def _get_device_type(self, ua):
    method _process_ip_address (line 74) | def _process_ip_address(self, addr):

FILE: src/backend/components/py.pi/caliopen_pi/features/helpers/histogram.py
  class ParticipantHistogram (line 11) | class ParticipantHistogram(object):
    method __init__ (line 14) | def __init__(self, user, resolution='day'):
    method _format_results (line 20) | def _format_results(self, results):
    method _do_query (line 25) | def _do_query(self, value, term):
    method find_by_address (line 41) | def find_by_address(self, address):
    method find_by_contact_id (line 45) | def find_by_contact_id(self, contact_id):

FILE: src/backend/components/py.pi/caliopen_pi/features/helpers/importance_level.py
  function get_importance_tags (line 28) | def get_importance_tags(tags):
  function compute_importance (line 38) | def compute_importance(user, message, features, participants):

FILE: src/backend/components/py.pi/caliopen_pi/features/helpers/ingress_path.py
  function normalize_ssocket_infos (line 19) | def normalize_ssocket_infos(socket_info, cipher):
  function get_ingress_features (line 28) | def get_ingress_features(headers, internal_domains=None):

FILE: src/backend/components/py.pi/caliopen_pi/features/helpers/spam.py
  function extract_mail_spam_scores (line 11) | def extract_mail_spam_scores(mail):
  class SpamScorer (line 44) | class SpamScorer(object):
    method __init__ (line 52) | def __init__(self, mail):

FILE: src/backend/components/py.pi/caliopen_pi/features/mail.py
  class InboundMailFeature (line 28) | class InboundMailFeature(object):
    method __init__ (line 31) | def __init__(self, message, config):
    method is_blacklist_mx (line 37) | def is_blacklist_mx(self, mx):
    method is_whitelist_mx (line 46) | def is_whitelist_mx(self, mx):
    method internal_domains (line 56) | def internal_domains(self):
    method emitter_reputation (line 61) | def emitter_reputation(self, mx):
    method emitter_certificate (line 69) | def emitter_certificate(self):
    method mail_agent (line 74) | def mail_agent(self):
    method transport_signature (line 80) | def transport_signature(self):
    method spam_informations (line 85) | def spam_informations(self):
    method is_internal (line 93) | def is_internal(self):
    method get_signature_informations (line 101) | def get_signature_informations(self):
    method get_encryption_informations (line 117) | def get_encryption_informations(self):
    method _get_features (line 136) | def _get_features(self):
    method _compute_pi (line 155) | def _compute_pi(self, participants, features):
    method process (line 203) | def process(self, user, message, participants):

FILE: src/backend/components/py.pi/caliopen_pi/features/types.py
  function check_feature_bounding (line 46) | def check_feature_bounding(value, feature):
  function find_feature (line 55) | def find_feature(name):
  function check_feature (line 61) | def check_feature(name, value):
  function unmarshal_feature (line 83) | def unmarshal_feature(name, value):
  function unmarshal_features (line 99) | def unmarshal_features(features):
  function marshal_features (line 112) | def marshal_features(features):
  function init_features (line 121) | def init_features(type_):

FILE: src/backend/components/py.pi/caliopen_pi/qualifiers/base.py
  class BaseQualifier (line 15) | class BaseQualifier(object):
    method __init__ (line 18) | def __init__(self, user, identity):
    method _get_tags (line 23) | def _get_tags(self, message):
    method lookup (line 33) | def lookup(self, sequence):
    method create_lookups (line 48) | def create_lookups(self, sequence, message):
    method get_participant (line 59) | def get_participant(self, message, participant):

FILE: src/backend/components/py.pi/caliopen_pi/qualifiers/contact.py
  class ContactMessageQualifier (line 14) | class ContactMessageQualifier(object):
    method __init__ (line 17) | def __init__(self, user):
    method process (line 20) | def process(self, contact):
  class ContactEmailQualifier (line 52) | class ContactEmailQualifier(object):
    method __init__ (line 61) | def __init__(self, user):
    method _process_new_keys (line 67) | def _process_new_keys(self, contact, keys):
    method create_new_email (line 97) | def create_new_email(self, contact, email):

FILE: src/backend/components/py.pi/caliopen_pi/qualifiers/device.py
  class NewDeviceQualifier (line 14) | class NewDeviceQualifier(object):
    method __init__ (line 17) | def __init__(self, user):
    method process (line 22) | def process(self, device):

FILE: src/backend/components/py.pi/caliopen_pi/qualifiers/mail.py
  class UserMessageQualifier (line 24) | class UserMessageQualifier(BaseQualifier):
    method lookup_discussion_sequence (line 40) | def lookup_discussion_sequence(self, mail, message):
    method process_inbound (line 82) | def process_inbound(self, raw):

FILE: src/backend/components/py.pi/caliopen_pi/qualifiers/mastodon.py
  class UserMastodonQualifier (line 18) | class UserMastodonQualifier(BaseQualifier):
    method lookup_discussion_sequence (line 25) | def lookup_discussion_sequence(self, message, *args, **kwargs):
    method process_inbound (line 34) | def process_inbound(self, raw):

FILE: src/backend/components/py.pi/caliopen_pi/qualifiers/twitter.py
  class UserTwitterQualifier (line 18) | class UserTwitterQualifier(BaseQualifier):
    method lookup_discussion_sequence (line 25) | def lookup_discussion_sequence(self, message, *args, **kwargs):
    method process_inbound (line 34) | def process_inbound(self, raw):

FILE: src/backend/components/py.pi/caliopen_pi/tests/test_features.py
  class FakeUser (line 23) | class FakeUser(object):
  function load_mail (line 29) | def load_mail(filename):
  class TestEncyption (line 40) | class TestEncyption(unittest.TestCase):
    method test_no_encryption_signature (line 43) | def test_no_encryption_signature(self):
    method test_transport_signature (line 57) | def test_transport_signature(self):
    method test_encrypted_message (line 67) | def test_encrypted_message(self):

FILE: src/backend/components/py.pi/caliopen_pi/tests/test_importance_level.py
  class MockPI (line 19) | class MockPI(object):
    method __init__ (line 21) | def __init__(self, technic, context, comportment):
  class MockMessage (line 27) | class MockMessage(object):
    method __init__ (line 29) | def __init__(self, pi, tags=None, refs=None):
  class TestInboundImportanceLevel (line 35) | class TestInboundImportanceLevel(unittest.TestCase):
    method test_max_spam (line 37) | def test_max_spam(self):
    method test_half_spam (line 44) | def test_half_spam(self):
    method test_max_pi_context (line 51) | def test_max_pi_context(self):
    method test_max_pi_comportment (line 58) | def test_max_pi_comportment(self):
    method test_max_pi_context_comportment (line 65) | def test_max_pi_context_comportment(self):

FILE: src/backend/components/py.pi/caliopen_pi/tests/test_spam.py
  function load_mail (line 20) | def load_mail(filename):
  class TestSpamScorer (line 31) | class TestSpamScorer(unittest.TestCase):
    method test_spam1 (line 34) | def test_spam1(self):
    method test_spam2 (line 41) | def test_spam2(self):
    method test_spam3 (line 48) | def test_spam3(self):

FILE: src/backend/components/py.tag/caliopen_tag/models_manager/data_manager.py
  class UsenetDataManager (line 9) | class UsenetDataManager(FileDataProvider):
    method _format_item (line 11) | def _format_item(cls, item):
  class ESDataManager (line 16) | class ESDataManager(ESProvider):
    method _format_item (line 18) | def _format_item(cls, item):
    method get_query (line 26) | def get_query(self):
  class MultipleSourceDataManager (line 33) | class MultipleSourceDataManager(object):
    method __init__ (line 34) | def __init__(self, providers):
    method next (line 37) | def next(self):

FILE: src/backend/components/py.tag/caliopen_tag/models_manager/manager.py
  class ModelManager (line 14) | class ModelManager(object):
    method __init__ (line 20) | def __init__(
    method get_new_model (line 48) | def get_new_model(self, output):
    method _write_training_data_to_file (line 62) | def _write_training_data_to_file(self):
    method _train_tagging_model (line 76) | def _train_tagging_model(self, output, quantization=False):
    method _remove_tempfile (line 104) | def _remove_tempfile(self):

FILE: src/backend/components/py.tag/caliopen_tag/taggers/tagger.py
  class MessageTagger (line 13) | class MessageTagger(object):
    method __init__ (line 16) | def __init__(self, model_name="model_cat1", k=5, threshold=0):
    method process (line 30) | def process(self, msg):

FILE: src/backend/components/py.tag/caliopen_tag/tests/test_model_manager.py
  class MockMessage (line 18) | class MockMessage:
    method __init__ (line 19) | def __init__(self, content, tags):
  class TestModelManager (line 24) | class TestModelManager(unittest.TestCase):
    method test_ESDataManager_format_item (line 27) | def test_ESDataManager_format_item(self):

FILE: src/backend/components/py.tag/caliopen_tag/tests/test_tag.py
  class TestPredictTagger (line 9) | class TestPredictTagger(unittest.TestCase):
    method test_tagger_load_fail_file_not_found (line 12) | def test_tagger_load_fail_file_not_found(self):
    method test_prepare_msg (line 16) | def test_prepare_msg(self):

FILE: src/backend/components/py.tag/caliopen_tag/utils.py
  function pre_process (line 7) | def pre_process(text, html=False):

FILE: src/backend/defs/go-objects/actions_payload.go
  type ActionsPayload (line 9) | type ActionsPayload struct

FILE: src/backend/defs/go-objects/attachment.go
  type Attachment (line 13) | type Attachment struct
    method UnmarshalMap (line 23) | func (a *Attachment) UnmarshalMap(input map[string]interface{}) error {
    method JSONMarshaller (line 50) | func (a *Attachment) JSONMarshaller() ([]byte, error) {
    method MarshalFrontEnd (line 55) | func (a *Attachment) MarshalFrontEnd() ([]byte, error) {
    method MarshallNew (line 60) | func (a *Attachment) MarshallNew(...interface{}) {
    method UnmarshalJSON (line 66) | func (a *Attachment) UnmarshalJSON(b []byte) error {
    method NewEmpty (line 75) | func (a *Attachment) NewEmpty() interface{} {
    method JsonTags (line 79) | func (a *Attachment) JsonTags() map[string]string {
    method SortSlices (line 83) | func (a *Attachment) SortSlices() {
  type ByFileName (line 88) | type ByFileName
    method Len (line 90) | func (a ByFileName) Len() int {
    method Less (line 94) | func (a ByFileName) Less(i, j int) bool {
    method Swap (line 98) | func (a ByFileName) Swap(i, j int) {

FILE: src/backend/defs/go-objects/cache.go
  type TokenSession (line 10) | type TokenSession struct

FILE: src/backend/defs/go-objects/common.go
  type CaliopenObject (line 19) | type CaliopenObject interface
  type HasNested (line 34) | type HasNested interface
  type HasRelated (line 39) | type HasRelated interface
  type HasLookup (line 45) | type HasLookup interface
  type NewMarshaller (line 50) | type NewMarshaller interface
  type StoreLookup (line 54) | type StoreLookup interface
  type FrontEndMarshaller (line 59) | type FrontEndMarshaller interface
  type ObjectPatchable (line 63) | type ObjectPatchable interface
  function jsonTags (line 75) | func jsonTags(obj interface{}) (tags map[string]string) {
  function MarshalNested (line 92) | func MarshalNested(obj HasNested) {
  function MarshalRelated (line 101) | func MarshalRelated(obj HasRelated) {
  function JSONMarshaller (line 112) | func JSONMarshaller(context string, obj interface{}) ([]byte, error) {
  function marshallField (line 149) | func marshallField(obj interface{}, field, context string, jsonBuf *byte...
  function isEmptyValue (line 247) | func isEmptyValue(v reflect.Value) bool {

FILE: src/backend/defs/go-objects/configs.go
  type CaliopenConfig (line 8) | type CaliopenConfig struct
  type RESTstoreConfig (line 19) | type RESTstoreConfig struct
  type RESTIndexConfig (line 31) | type RESTIndexConfig struct
  type CacheConfig (line 37) | type CacheConfig struct
  type NatsConfig (line 44) | type NatsConfig struct
  type StoreConfig (line 57) | type StoreConfig struct
  type IndexConfig (line 69) | type IndexConfig struct
  type OSSConfig (line 74) | type OSSConfig struct
  type NotifierConfig (line 83) | type NotifierConfig struct
  type VaultConfig (line 90) | type VaultConfig struct
  type ProvidersConfig (line 97) | type ProvidersConfig struct
  type LDAConfig (line 101) | type LDAConfig struct

FILE: src/backend/defs/go-objects/constants.go
  constant EmailProtocol (line 11) | EmailProtocol     = "email"
  constant ImapProtocol (line 12) | ImapProtocol      = "imap"
  constant SmtpProtocol (line 13) | SmtpProtocol      = "smtp"
  constant IrcProtocol (line 14) | IrcProtocol       = "irc"
  constant SmsProtocol (line 15) | SmsProtocol       = "sms"
  constant XmppProtocol (line 16) | XmppProtocol      = "xmpp"
  constant FacebookProtocl (line 17) | FacebookProtocl   = "facebook"
  constant TwitterProtocol (line 18) | TwitterProtocol   = "twitter"
  constant GnuSocialProtocol (line 19) | GnuSocialProtocol = "GNUsocial"
  constant MastodonProtocol (line 20) | MastodonProtocol  = "mastodon"
  constant TimeISO8601 (line 22) | TimeISO8601      = "2006-01-02T15:04:05-07:00"
  constant TimeUTCmicro (line 23) | TimeUTCmicro     = "2006-01-02T15:04:05.999999"
  constant RFC3339Milli (line 24) | RFC3339Milli     = "2006-01-02T15:04:05.000Z07:00"
  constant MessageType (line 25) | MessageType      = "message"
  constant ContactType (line 26) | ContactType      = "contact"
  constant MessageIndexType (line 27) | MessageIndexType = "indexed_message"
  constant ContactIndexType (line 28) | ContactIndexType = "indexed_contact"
  constant LoginPassword (line 31) | LoginPassword = "login-password"
  constant Oauth1 (line 32) | Oauth1        = "Oauth1"
  constant Oauth2 (line 33) | Oauth2        = "Oauth2"
  constant Nats_contact_tmpl (line 36) | Nats_contact_tmpl         = "{\"order\":\"%s\", \"contact_id\":\"%s\", \...
  constant Nats_outSMTP_topicKey (line 37) | Nats_outSMTP_topicKey     = "outSMTP_topic"
  constant Nats_inSMTP_topicKey (line 38) | Nats_inSMTP_topicKey      = "inSMTP_topic"
  constant Nats_Contacts_topicKey (line 39) | Nats_Contacts_topicKey    = "contacts_topic"
  constant Nats_outIMAP_topicKey (line 40) | Nats_outIMAP_topicKey     = "outIMAP_topic"
  constant Nats_outTwitter_topicKey (line 41) | Nats_outTwitter_topicKey  = "outTWITTER_topic"
  constant Nats_outMastodon_topicKey (line 42) | Nats_outMastodon_topicKey = "outMASTODON_topic"
  constant Nats_Keys_topicKey (line 43) | Nats_Keys_topicKey        = "keys_topic"
  constant Nats_IdPoller_topicKey (line 44) | Nats_IdPoller_topicKey    = "idpoller_topic"
  constant ParticipantBcc (line 47) | ParticipantBcc     = "Bcc"
  constant ParticipantCC (line 48) | ParticipantCC      = "Cc"
  constant ParticipantFrom (line 49) | ParticipantFrom    = "From"
  constant ParticipantReplyTo (line 50) | ParticipantReplyTo = "Reply-To"
  constant ParticipantSender (line 51) | ParticipantSender  = "Sender"
  constant ParticipantTo (line 52) | ParticipantTo      = "To"
  constant NotifAdminMail (line 55) | NotifAdminMail        = "adminMail"
  constant NotifPasswordReset (line 56) | NotifPasswordReset    = "passwordReset"
  constant NotifDeviceValidation (line 57) | NotifDeviceValidation = "deviceValidation"
  constant OnboardingMails (line 58) | OnboardingMails       = "onboardingMails"
  constant LocalIdentity (line 61) | LocalIdentity  = "local"
  constant RemoteIdentity (line 62) | RemoteIdentity = "remote"
  constant UrisKind (line 65) | UrisKind         = "uris"
  constant ParticipantsKind (line 66) | ParticipantsKind = "participants"
  constant DeviceVerifiedStatus (line 69) | DeviceVerifiedStatus   = "verified"
  constant DeviceUnverifiedStatus (line 70) | DeviceUnverifiedStatus = "unverified"
  constant DeviceDeletedStatus (line 71) | DeviceDeletedStatus    = "deleted"
  constant DeviceOtherType (line 74) | DeviceOtherType      = "other"
  constant DeviceDesktopType (line 75) | DeviceDesktopType    = "desktop"
  constant DeviceLaptopType (line 76) | DeviceLaptopType     = "laptop"
  constant DeviceSmartphoneType (line 77) | DeviceSmartphoneType = "smartphone"
  constant DeviceTabletType (line 78) | DeviceTabletType     = "tablet"
  constant RSA256 (line 82) | RSA256   = "RS256"
  constant RSA384 (line 83) | RSA384   = "RS384"
  constant RSA512 (line 84) | RSA512   = "RS512"
  constant ECDSA256 (line 85) | ECDSA256 = "ES256"
  constant ECDSA384 (line 86) | ECDSA384 = "ES384"
  constant DSA256 (line 88) | DSA256     = "DSA256"
  constant DSA384 (line 89) | DSA384     = "DSA384"
  constant DSA512 (line 90) | DSA512     = "DSA512"
  constant ELGAMAL256 (line 91) | ELGAMAL256 = "ELGAMAL256"
  constant ELGAMAL384 (line 92) | ELGAMAL384 = "ELGAMAL384"
  constant ELGAMAL512 (line 93) | ELGAMAL512 = "ELGAMAL512"
  constant ECDH256 (line 94) | ECDH256    = "ECDH256"
  constant ECDH384 (line 95) | ECDH384    = "ECDH384"
  constant ECDH512 (line 96) | ECDH512    = "ECDH512"
  constant CURVE256 (line 98) | CURVE256 = "P-256"
  constant CURVE384 (line 99) | CURVE384 = "P-384"
  constant CURVE521 (line 100) | CURVE521 = "P-521"
  constant RSA_KEY_TYPE (line 102) | RSA_KEY_TYPE   = "RSA"
  constant EC_KEY_TYPE (line 103) | EC_KEY_TYPE    = "EC"
  constant OCTET_KEY_TYPE (line 104) | OCTET_KEY_TYPE = "oct"
  constant PGP_KEY_TYPE (line 106) | PGP_KEY_TYPE     = "PGP"
  constant DSA_KEY_TYPE (line 107) | DSA_KEY_TYPE     = "DSA"
  constant ELGAMAL_KEY_TYPE (line 108) | ELGAMAL_KEY_TYPE = "ELGAMAL"
  constant SIGNATURE_KEY (line 110) | SIGNATURE_KEY  = "sig"
  constant ENCRYPTION_KEY (line 111) | ENCRYPTION_KEY = "enc"
  type Initiator (line 116) | type Initiator
  constant Unknown (line 119) | Unknown Initiator = iota
  constant SystemActor (line 120) | SystemActor
  constant UserActor (line 121) | UserActor

FILE: src/backend/defs/go-objects/contact.go
  type Contact (line 17) | type Contact struct
    method UnmarshalCQLMap (line 56) | func (contact *Contact) UnmarshalCQLMap(input map[string]interface{}) {
    method UnmarshalJSON (line 217) | func (c *Contact) UnmarshalJSON(b []byte) error {
    method UnmarshalMap (line 227) | func (c *Contact) UnmarshalMap(input map[string]interface{}) error {
    method MarshalFrontEnd (line 377) | func (c *Contact) MarshalFrontEnd() ([]byte, error) {
    method MarshalES (line 381) | func (c *Contact) MarshalES() ([]byte, error) {
    method JSONMarshaller (line 388) | func (c *Contact) JSONMarshaller() ([]byte, error) {
    method JsonTags (line 392) | func (c *Contact) JsonTags() map[string]string {
    method NewEmpty (line 396) | func (c *Contact) NewEmpty() interface{} {
    method GetSetNested (line 413) | func (c *Contact) GetSetNested() <-chan interface{} {
    method GetRelatedList (line 452) | func (c *Contact) GetRelatedList() map[string]interface{} {
    method GetSetRelated (line 463) | func (c *Contact) GetSetRelated() <-chan interface{} {
    method GetLookupsTables (line 484) | func (c *Contact) GetLookupsTables() map[string]StoreLookup {
    method SortSlices (line 493) | func (c *Contact) SortSlices() {
    method MarshallNew (line 506) | func (c *Contact) MarshallNew(args ...interface{}) {
    method GetLookupKeys (line 553) | func (c *Contact) GetLookupKeys() <-chan StoreLookup {
  type ContactByContactPoints (line 46) | type ContactByContactPoints struct
    method UpdateLookups (line 608) | func (lookup *ContactByContactPoints) UpdateLookups(contacts ...interf...
    method CleanupLookups (line 691) | func (lookup *ContactByContactPoints) CleanupLookups(contacts ...inter...
  function UpdateURIWithContact (line 724) | func UpdateURIWithContact(session *gocql.Session, userId, uri string) er...
  function ContactsForParticipants (line 796) | func ContactsForParticipants(session *gocql.Session, userId string, part...

FILE: src/backend/defs/go-objects/credentials.go
  type Credentials (line 9) | type Credentials
    method UnmarshalMap (line 11) | func (cred *Credentials) UnmarshalMap(input map[string]interface{}) {
    method UnmarshalCQLMap (line 17) | func (cred *Credentials) UnmarshalCQLMap(input map[string]string) {

FILE: src/backend/defs/go-objects/crypto_keys.go
  type PublicKey (line 25) | type PublicKey struct
    method UnmarshalCQLMap (line 66) | func (pk *PublicKey) UnmarshalCQLMap(input map[string]interface{}) {
    method UnmarshalMap (line 126) | func (pk *PublicKey) UnmarshalMap(input map[string]interface{}) error {
    method UnmarshalJSON (line 193) | func (pk *PublicKey) UnmarshalJSON(b []byte) error {
    method UnmarshalPGPEntity (line 204) | func (pk *PublicKey) UnmarshalPGPEntity(label string, entity *openpgp....
    method GetTableInfos (line 370) | func (pk *PublicKey) GetTableInfos() (table string, partitionKeys map[...
    method MarshallNew (line 383) | func (pk *PublicKey) MarshallNew(contacts ...interface{}) {
    method MarshalFrontEnd (line 403) | func (pk *PublicKey) MarshalFrontEnd() ([]byte, error) {
    method JSONMarshaller (line 407) | func (pk *PublicKey) JSONMarshaller() ([]byte, error) {
    method NewEmpty (line 411) | func (pk *PublicKey) NewEmpty() interface{} {
    method JsonTags (line 417) | func (pk *PublicKey) JsonTags() map[string]string {
    method SortSlices (line 421) | func (pk *PublicKey) SortSlices() {
  type DiscoverKeyMessage (line 48) | type DiscoverKeyMessage struct
  type PublishKeyMessage (line 57) | type PublishKeyMessage struct
  function GetExpiryDate (line 354) | func GetExpiryDate(s *packet.Signature) time.Time {
  function ExtractEmailAddrFromString (line 363) | func ExtractEmailAddrFromString(s string) string {
  type PublicKeys (line 425) | type PublicKeys
  type ByKeyId (line 428) | type ByKeyId
    method Len (line 430) | func (p ByKeyId) Len() int {
    method Less (line 434) | func (p ByKeyId) Less(i, j int) bool {
    method Swap (line 438) | func (p ByKeyId) Swap(i, j int) {

FILE: src/backend/defs/go-objects/device.go
  type Device (line 20) | type Device struct
    method UnmarshalCQLMap (line 46) | func (d *Device) UnmarshalCQLMap(input map[string]interface{}) {
    method UnmarshalMap (line 102) | func (d *Device) UnmarshalMap(input map[string]interface{}) error {
    method UnmarshalJSON (line 169) | func (d *Device) UnmarshalJSON(b []byte) error {
    method MarshalFrontEnd (line 179) | func (d *Device) MarshalFrontEnd() ([]byte, error) {
    method JSONMarshaller (line 186) | func (d *Device) JSONMarshaller() ([]byte, error) {
    method NewEmpty (line 190) | func (d *Device) NewEmpty() interface{} {
    method MarshallNew (line 196) | func (d *Device) MarshallNew(args ...interface{}) {
    method JsonTags (line 222) | func (d *Device) JsonTags() map[string]string {
    method SortSlices (line 226) | func (d *Device) SortSlices() {
    method GetRelatedList (line 231) | func (d *Device) GetRelatedList() map[string]interface{} {
    method GetSetRelated (line 238) | func (d *Device) GetSetRelated() <-chan interface{} {
  type DeviceValidationRequest (line 39) | type DeviceValidationRequest struct
  function IsValidDeviceType (line 266) | func IsValidDeviceType(t string) bool {
  function DefaultDeviceType (line 277) | func DefaultDeviceType() string {

FILE: src/backend/defs/go-objects/discussion.go
  type Discussion (line 15) | type Discussion struct
    method UnmarshalJSON (line 36) | func (d *Discussion) UnmarshalJSON(b []byte) error {
    method UnmarshalMap (line 46) | func (d *Discussion) UnmarshalMap(input map[string]interface{}) error {
    method JSONMarshaller (line 114) | func (d *Discussion) JSONMarshaller() ([]byte, error) {
    method MarshalFrontEnd (line 119) | func (d *Discussion) MarshalFrontEnd() ([]byte, error) {
    method MarshallNew (line 124) | func (d *Discussion) MarshallNew(args ...interface{}) {
  type ByLastMessageDateDesc (line 139) | type ByLastMessageDateDesc
    method Len (line 141) | func (blm ByLastMessageDateDesc) Len() int {
    method Less (line 145) | func (blm ByLastMessageDateDesc) Less(i, j int) bool {
    method Swap (line 149) | func (blm ByLastMessageDateDesc) Swap(i, j int) {

FILE: src/backend/defs/go-objects/email.go
  type EmailMessage (line 12) | type EmailMessage struct
  type Email (line 19) | type Email struct
  type EmailJson (line 28) | type EmailJson struct
    method ExtractAttachments (line 89) | func (email EmailJson) ExtractAttachments(index ...int) (attachments [...
  type EmailAddress (line 40) | type EmailAddress struct
  type Envelope (line 45) | type Envelope struct
  type MimeRoot (line 55) | type MimeRoot struct
  type Part (line 62) | type Part struct
  type Parts (line 73) | type Parts
    method Walk (line 115) | func (parts Parts) Walk() (partChan chan Part) {
  type EmailContact (line 76) | type EmailContact struct
    method UnmarshalMap (line 135) | func (ec *EmailContact) UnmarshalMap(input map[string]interface{}) err...
    method MarshallNew (line 150) | func (ec *EmailContact) MarshallNew(...interface{}) {
  type ByEmailContactID (line 157) | type ByEmailContactID
    method Len (line 159) | func (p ByEmailContactID) Len() int {
    method Less (line 163) | func (p ByEmailContactID) Less(i, j int) bool {
    method Swap (line 167) | func (p ByEmailContactID) Swap(i, j int) {

FILE: src/backend/defs/go-objects/errors.go
  type CaliopenErr (line 15) | type CaliopenErr struct
    method Error (line 27) | func (ce CaliopenErr) Error() string {
    method Code (line 31) | func (ce CaliopenErr) Code() int32 {
    method Cause (line 35) | func (ce CaliopenErr) Cause() error {
  type CaliopenError (line 21) | type CaliopenError interface
  function NewCaliopenErr (line 38) | func NewCaliopenErr(code int, msg string) CaliopenErr {
  function NewCaliopenErrf (line 42) | func NewCaliopenErrf(code int, format string, a ...interface{}) Caliopen...
  function WrapCaliopenErrf (line 50) | func WrapCaliopenErrf(err error, code int, format string, a ...interface...
  function WrapCaliopenErr (line 63) | func WrapCaliopenErr(err error, code int, msg string) CaliopenErr {
  constant UnknownCaliopenErr (line 78) | UnknownCaliopenErr = iota
  constant DbCaliopenErr (line 79) | DbCaliopenErr
  constant IndexCaliopenErr (line 80) | IndexCaliopenErr
  constant NotFoundCaliopenErr (line 81) | NotFoundCaliopenErr
  constant FailDependencyCaliopenErr (line 82) | FailDependencyCaliopenErr
  constant UnprocessableCaliopenErr (line 83) | UnprocessableCaliopenErr
  constant ForbiddenCaliopenErr (line 84) | ForbiddenCaliopenErr
  constant NotImplementedCaliopenErr (line 85) | NotImplementedCaliopenErr
  constant WrongCredentialsErr (line 86) | WrongCredentialsErr
  constant DuplicateMessage (line 88) | DuplicateMessage = "message already imported for this user"

FILE: src/backend/defs/go-objects/external_references.go
  type ExternalReferences (line 7) | type ExternalReferences struct
    method UnmarshalMap (line 13) | func (er *ExternalReferences) UnmarshalMap(input map[string]interface{...

FILE: src/backend/defs/go-objects/im.go
  type IM (line 13) | type IM struct
    method UnmarshalMap (line 22) | func (i *IM) UnmarshalMap(input map[string]interface{}) error {
    method MarshallNew (line 39) | func (i *IM) MarshallNew(...interface{}) {
  type ByIMID (line 46) | type ByIMID
    method Len (line 48) | func (p ByIMID) Len() int {
    method Less (line 52) | func (p ByIMID) Less(i, j int) bool {
    method Swap (line 56) | func (p ByIMID) Swap(i, j int) {

FILE: src/backend/defs/go-objects/location.go
  type DeviceLocation (line 16) | type DeviceLocation struct
    method UnmarshalMap (line 27) | func (dl *DeviceLocation) UnmarshalMap(input map[string]interface{}) e...
    method UnmarshalCQLMap (line 50) | func (dl *DeviceLocation) UnmarshalCQLMap(input map[string]interface{}) {
    method GetTableInfos (line 70) | func (dl *DeviceLocation) GetTableInfos() (table string, partitionKeys...
    method MarshallNew (line 84) | func (dl *DeviceLocation) MarshallNew(args ...interface{}) {
    method NewEmpty (line 103) | func (dl *DeviceLocation) NewEmpty() interface{} {
    method UnmarshalJSON (line 107) | func (dl *DeviceLocation) UnmarshalJSON(b []byte) error {
    method MarshalFrontEnd (line 116) | func (dl *DeviceLocation) MarshalFrontEnd() ([]byte, error) {
    method JSONMarshaller (line 120) | func (dl *DeviceLocation) JSONMarshaller() ([]byte, error) {
    method JsonTags (line 124) | func (dl *DeviceLocation) JsonTags() map[string]string {
    method SortSlices (line 128) | func (dl *DeviceLocation) SortSlices() {
  type DeviceLocations (line 25) | type DeviceLocations
  type ByIpAddress (line 133) | type ByIpAddress
    method Len (line 135) | func (a ByIpAddress) Len() int {
    method Less (line 139) | func (a ByIpAddress) Less(i, j int) bool {
    method Swap (line 143) | func (a ByIpAddress) Swap(i, j int) {

FILE: src/backend/defs/go-objects/message.go
  type PIMessage (line 18) | type PIMessage struct
  type Message (line 24) | type Message struct
    method JSONMarshaller (line 59) | func (msg *Message) JSONMarshaller(context string, body_type ...string...
    method MarshalJSON (line 136) | func (msg *Message) MarshalJSON() ([]byte, error) {
    method MarshalES (line 140) | func (msg *Message) MarshalES() ([]byte, error) {
    method MarshalFrontEnd (line 145) | func (msg *Message) MarshalFrontEnd(body_type string) ([]byte, error) {
    method UnmarshalJSON (line 149) | func (msg *Message) UnmarshalJSON(b []byte) error {
    method UnmarshalMap (line 157) | func (msg *Message) UnmarshalMap(input map[string]interface{}) error {
    method UnmarshalCQLMap (line 280) | func (msg *Message) UnmarshalCQLMap(input map[string]interface{}) error {
    method NewEmpty (line 424) | func (msg *Message) NewEmpty() interface{} {
    method MarshallNew (line 435) | func (msg *Message) MarshallNew(args ...interface{}) {
    method JsonTags (line 467) | func (msg *Message) JsonTags() (tags map[string]string) {
    method SortSlices (line 471) | func (msg *Message) SortSlices() {
  type Messages (line 54) | type Messages
  type ByDateSortAsc (line 479) | type ByDateSortAsc
    method Len (line 481) | func (ds ByDateSortAsc) Len() int {
    method Less (line 485) | func (ds ByDateSortAsc) Less(i, j int) bool {
    method Swap (line 489) | func (ds ByDateSortAsc) Swap(i, j int) {
  function MessagesParticipantsDetails (line 495) | func MessagesParticipantsDetails(session *gocql.Session, messages []Mess...
  function DiscussionsParticipantsDetails (line 524) | func DiscussionsParticipantsDetails(session *gocql.Session, discussions ...

FILE: src/backend/defs/go-objects/nats.go
  type DeliveryAck (line 10) | type DeliveryAck struct
  type Ack (line 16) | type Ack struct
  type WorkerRequest (line 23) | type WorkerRequest struct
  type RemoteIDNatsMessage (line 29) | type RemoteIDNatsMessage struct
  type BrokerOrder (line 38) | type BrokerOrder struct
  type IMAPorder (line 46) | type IMAPorder struct

FILE: src/backend/defs/go-objects/notification.go
  type Notification (line 15) | type Notification struct
    method MarshalFrontEnd (line 71) | func (n *Notification) MarshalFrontEnd() ([]byte, error) {
    method UnmarshalCQLMap (line 99) | func (n *Notification) UnmarshalCQLMap(input map[string]interface{}) {
  type NotificationModel (line 29) | type NotificationModel struct
    method MarshalJSON (line 153) | func (n *NotificationModel) MarshalJSON() ([]byte, error) {
  type NotificationTTL (line 41) | type NotificationTTL struct
  constant EventNotif (line 50) | EventNotif      = "event"
  constant NewMessageNotif (line 51) | NewMessageNotif = "new_message"
  constant InfoNotif (line 52) | InfoNotif       = "info"
  constant FeedbackNotif (line 53) | FeedbackNotif   = "feedback"
  constant WarningNotif (line 54) | WarningNotif    = "warning"
  constant TeaserNotif (line 55) | TeaserNotif     = "teaser"
  constant ErrorNotif (line 56) | ErrorNotif      = "error"
  constant AlertNotif (line 57) | AlertNotif      = "alert"
  constant BatchNotif (line 58) | BatchNotif      = "batch"
  constant ShortLived (line 61) | ShortLived = "short-lived"
  constant MidLived (line 62) | MidLived   = "mid-lived"
  constant LongLived (line 63) | LongLived  = "long-lived"
  constant ShortTerm (line 64) | ShortTerm  = "short-term"
  constant MidTerm (line 65) | MidTerm    = "mid-term"
  constant LongTerm (line 66) | LongTerm   = "long-term"
  constant Forever (line 67) | Forever    = "forever"

FILE: src/backend/defs/go-objects/notification_test.go
  function TestNotification_UnmarshalCQLMap (line 10) | func TestNotification_UnmarshalCQLMap(t *testing.T) {

FILE: src/backend/defs/go-objects/organization.go
  type Organization (line 13) | type Organization struct
    method UnmarshalMap (line 25) | func (o *Organization) UnmarshalMap(input map[string]interface{}) error {
    method MarshallNew (line 60) | func (o *Organization) MarshallNew(...interface{}) {
  type ByOrganizationID (line 67) | type ByOrganizationID
    method Len (line 69) | func (p ByOrganizationID) Len() int {
    method Less (line 73) | func (p ByOrganizationID) Less(i, j int) bool {
    method Swap (line 77) | func (p ByOrganizationID) Swap(i, j int) {

FILE: src/backend/defs/go-objects/participant.go
  type Participant (line 19) | type Participant struct
    method UnmarshalMap (line 45) | func (p *Participant) UnmarshalMap(input map[string]interface{}) error {
    method MarshallNew (line 92) | func (p *Participant) MarshallNew(...interface{}) {
  type HashLookup (line 27) | type HashLookup struct
    method UnmarshalCQLMap (line 72) | func (pl *HashLookup) UnmarshalCQLMap(input map[string]interface{}) er...
    method MarshallNew (line 96) | func (pl *HashLookup) MarshallNew(args ...interface{}) {
  type ParticipantHash (line 35) | type ParticipantHash struct
    method UnmarshalCQLMap (line 108) | func (hl *ParticipantHash) UnmarshalCQLMap(input map[string]interface{...
  type ByAddress (line 131) | type ByAddress
    method Len (line 133) | func (p ByAddress) Len() int {
    method Less (line 137) | func (p ByAddress) Less(i, j int) bool {
    method Swap (line 141) | func (p ByAddress) Swap(i, j int) {
  function HashFromParticipantsUris (line 146) | func HashFromParticipantsUris(participants []Participant) (hash string, ...
  function HashComponents (line 160) | func HashComponents(c []string) string {
  function StoreURIsParticipantsBijection (line 168) | func StoreURIsParticipantsBijection(session *gocql.Session, userId, uriH...
  function RemoveURIsParticipantsBijection (line 188) | func RemoveURIsParticipantsBijection(session *gocql.Session, former Part...

FILE: src/backend/defs/go-objects/participants_test.go
  function TestHashFromParticipantsUris (line 27) | func TestHashFromParticipantsUris(t *testing.T) {

FILE: src/backend/defs/go-objects/phone.go
  type Phone (line 14) | type Phone struct
    method UnmarshalMap (line 23) | func (p *Phone) UnmarshalMap(input map[string]interface{}) error {
    method MarshallNew (line 49) | func (p *Phone) MarshallNew(...interface{}) {
    method JsonTags (line 55) | func (p *Phone) JsonTags() map[string]string {
    method NewEmpty (line 59) | func (p *Phone) NewEmpty() interface{} {
    method UnmarshalJSON (line 63) | func (p *Phone) UnmarshalJSON(b []byte) error {
  type ByPhoneID (line 73) | type ByPhoneID
    method Len (line 75) | func (p ByPhoneID) Len() int {
    method Less (line 79) | func (p ByPhoneID) Less(i, j int) bool {
    method Swap (line 83) | func (p ByPhoneID) Swap(i, j int) {

FILE: src/backend/defs/go-objects/postal_address.go
  type PostalAddress (line 13) | type PostalAddress struct
    method UnmarshalJSON (line 25) | func (pa *PostalAddress) UnmarshalJSON(b []byte) error {
    method UnmarshalMap (line 34) | func (pa *PostalAddress) UnmarshalMap(input map[string]interface{}) er...
    method MarshallNew (line 70) | func (pa *PostalAddress) MarshallNew(...interface{}) {
  type ByPostalAddressID (line 77) | type ByPostalAddressID
    method Len (line 79) | func (p ByPostalAddressID) Len() int {
    method Less (line 83) | func (p ByPostalAddressID) Less(i, j int) bool {
    method Swap (line 87) | func (p ByPostalAddressID) Swap(i, j int) {

FILE: src/backend/defs/go-objects/privacy_features.go
  type PrivacyFeatures (line 7) | type PrivacyFeatures
    method UnmarshalMap (line 9) | func (pf *PrivacyFeatures) UnmarshalMap(input map[string]interface{}) {

FILE: src/backend/defs/go-objects/privacy_index.go
  type PrivacyIndex (line 11) | type PrivacyIndex struct
    method UnmarshalMap (line 19) | func (pi *PrivacyIndex) UnmarshalMap(input map[string]interface{}) err...
    method JSONMarshaller (line 46) | func (pi *PrivacyIndex) JSONMarshaller() ([]byte, error) {
    method IsEmpty (line 50) | func (pi *PrivacyIndex) IsEmpty() bool {

FILE: src/backend/defs/go-objects/provider.go
  type Provider (line 8) | type Provider struct
    method MarshalFrontEnd (line 29) | func (p *Provider) MarshalFrontEnd() ([]byte, error) {
    method UnmarshalCQLmap (line 33) | func (p *Provider) UnmarshalCQLmap(input map[string]interface{}) error {
  type OauthSession (line 20) | type OauthSession struct

FILE: src/backend/defs/go-objects/raw_message.go
  type RawMessage (line 9) | type RawMessage struct
    method UnmarshalCQLMap (line 19) | func (msg *RawMessage) UnmarshalCQLMap(input map[string]interface{}) {

FILE: src/backend/defs/go-objects/search.go
  type IndexSearch (line 12) | type IndexSearch struct
    method FilterQuery (line 46) | func (is *IndexSearch) FilterQuery(service *elastic.SearchService, wit...
    method MatchQuery (line 77) | func (is *IndexSearch) MatchQuery(service *elastic.SearchService) *ela...
  type IndexResult (line 23) | type IndexResult struct
    method MarshalFrontEnd (line 87) | func (ir *IndexResult) MarshalFrontEnd() ([]byte, error) {
    method JSONMarshaller (line 93) | func (ir *IndexResult) JSONMarshaller(context string) ([]byte, error) {
  type MessageHits (line 29) | type MessageHits struct
  type ContactHits (line 34) | type ContactHits struct
  type IndexHit (line 39) | type IndexHit struct

FILE: src/backend/defs/go-objects/settings.go
  type Settings (line 14) | type Settings struct
    method UnmarshalCQLMap (line 28) | func (s *Settings) UnmarshalCQLMap(input map[string]interface{}) {
    method UnmarshalMap (line 41) | func (s *Settings) UnmarshalMap(input map[string]interface{}) error {
    method UnmarshalJSON (line 74) | func (s *Settings) UnmarshalJSON(b []byte) error {
    method NewEmpty (line 83) | func (*Settings) NewEmpty() interface{} {
    method JsonTags (line 87) | func (s *Settings) JsonTags() map[string]string {

FILE: src/backend/defs/go-objects/social_identity.go
  type SocialIdentity (line 14) | type SocialIdentity struct
    method UnmarshalMap (line 39) | func (si *SocialIdentity) UnmarshalMap(input map[string]interface{}) e...
    method MarshallNew (line 57) | func (si *SocialIdentity) MarshallNew(...interface{}) {
    method NewEmpty (line 63) | func (si *SocialIdentity) NewEmpty() interface{} {
  type ContactIdentity (line 22) | type ContactIdentity struct
  type RecipientSuggestion (line 30) | type RecipientSuggestion struct
  type BySocialIdentityID (line 70) | type BySocialIdentityID
    method Len (line 72) | func (p BySocialIdentityID) Len() int {
    method Less (line 76) | func (p BySocialIdentityID) Less(i, j int) bool {
    method Swap (line 80) | func (p BySocialIdentityID) Swap(i, j int) {

FILE: src/backend/defs/go-objects/tag.go
  type Tag (line 20) | type Tag struct
    method JSONMarshaller (line 41) | func (tag *Tag) JSONMarshaller(context string) ([]byte, error) {
    method MarshalFrontEnd (line 96) | func (tag *Tag) MarshalFrontEnd() ([]byte, error) {
    method UnmarshalMap (line 103) | func (tag *Tag) UnmarshalMap(input map[string]interface{}) error {
    method UnmarshalCQLMap (line 129) | func (tag *Tag) UnmarshalCQLMap(input map[string]interface{}) error {
    method UnmarshalJSON (line 140) | func (tag *Tag) UnmarshalJSON(b []byte) error {
    method JsonTags (line 149) | func (tag *Tag) JsonTags() (tags map[string]string) {
    method NewEmpty (line 153) | func (tag *Tag) NewEmpty() interface{} {
    method MarshallNew (line 158) | func (tag *Tag) MarshallNew(args ...interface{}) {
    method SortSlices (line 174) | func (tag *Tag) SortSlices() {
  type TagType (line 31) | type TagType
  constant UserTag (line 34) | UserTag   TagType = "user"
  constant SystemTag (line 35) | SystemTag TagType = "system"

FILE: src/backend/defs/go-objects/tls.go
  function init (line 10) | func init() {

FILE: src/backend/defs/go-objects/user.go
  type UserInfo (line 18) | type UserInfo struct
  type User (line 23) | type User struct
    method UnmarshalCQLMap (line 69) | func (user *User) UnmarshalCQLMap(input map[string]interface{}) {
    method UnmarshalJSON (line 111) | func (user *User) UnmarshalJSON(b []byte) error {
    method UnmarshalMap (line 120) | func (user *User) UnmarshalMap(input map[string]interface{}) error {
    method JSONMarshaller (line 174) | func (user *User) JSONMarshaller(context string, body_type ...string) ...
    method MarshalJSON (line 179) | func (user *User) MarshalJSON() ([]byte, error) {
    method MarshalFrontEnd (line 185) | func (user *User) MarshalFrontEnd(body_type string) ([]byte, error) {
    method JsonTags (line 191) | func (user *User) JsonTags() (tags map[string]string) {
    method NewEmpty (line 195) | func (user *User) NewEmpty() interface{} {
  type PasswordResetRequest (line 42) | type PasswordResetRequest struct
  type DeleteUserParams (line 48) | type DeleteUserParams struct
  type Auth_cache (line 54) | type Auth_cache struct
    method UnmarshalJSON (line 202) | func (ac *Auth_cache) UnmarshalJSON(b []byte) error {

FILE: src/backend/defs/go-objects/user_identity.go
  type UserIdentity (line 20) | type UserIdentity struct
    method NewEmpty (line 49) | func (ui *UserIdentity) NewEmpty() interface{} {
    method UnmarshalJSON (line 55) | func (ui *UserIdentity) UnmarshalJSON(b []byte) error {
    method UnmarshalMap (line 64) | func (ui *UserIdentity) UnmarshalMap(input map[string]interface{}) err...
    method JsonTags (line 108) | func (ui *UserIdentity) JsonTags() (tags map[string]string) {
    method SortSlices (line 112) | func (ui *UserIdentity) SortSlices() {
    method MarshallNew (line 117) | func (ui *UserIdentity) MarshallNew(args ...interface{}) {
    method SetDefaults (line 131) | func (ui *UserIdentity) SetDefaults() {
    method UnmarshalCQLMap (line 204) | func (ui *UserIdentity) UnmarshalCQLMap(input map[string]interface{}) ...
    method MarshalFrontEnd (line 243) | func (ui *UserIdentity) MarshalFrontEnd() ([]byte, error) {
    method GetLookupsTables (line 250) | func (userIdentity *UserIdentity) GetLookupsTables() map[string]StoreL...
    method GetLookupKeys (line 258) | func (userIdentity *UserIdentity) GetLookupKeys() <-chan StoreLookup {
  type IdentityLookup (line 36) | type IdentityLookup struct
    method CleanupLookups (line 279) | func (il *IdentityLookup) CleanupLookups(identities ...interface{}) fu...
    method UpdateLookups (line 298) | func (il *IdentityLookup) UpdateLookups(identities ...interface{}) fun...
  type IdentityTypeLookup (line 42) | type IdentityTypeLookup struct
    method CleanupLookups (line 366) | func (itl *IdentityTypeLookup) CleanupLookups(identities ...interface{...
    method UpdateLookups (line 382) | func (itl *IdentityTypeLookup) UpdateLookups(identities ...interface{}...
  type ByUUID (line 437) | type ByUUID
    method Len (line 439) | func (p ByUUID) Len() int {
    method Less (line 443) | func (p ByUUID) Less(i, j int) bool {
    method Swap (line 447) | func (p ByUUID) Swap(i, j int) {

FILE: src/backend/defs/go-objects/username.go
  type UserName (line 8) | type UserName struct
  type Availability (line 13) | type Availability struct

FILE: src/backend/defs/go-objects/uuid.go
  type UUID (line 9) | type UUID
    method MarshalCQL (line 14) | func (id UUID) MarshalCQL(info gocql.TypeInfo) ([]byte, error) {
    method UnmarshalCQL (line 18) | func (id *UUID) UnmarshalCQL(info gocql.TypeInfo, data []byte) error {
    method UnmarshalBinary (line 27) | func (id *UUID) UnmarshalBinary(data []byte) (err error) {
    method String (line 39) | func (id UUID) String() string {
    method MarshalJSON (line 55) | func (id UUID) MarshalJSON() ([]byte, error) {
    method Bytes (line 61) | func (id UUID) Bytes() []byte {
  constant dash (line 12) | dash byte = '-'

FILE: src/backend/interfaces/NATS/go.mockednats/nats.go
  constant natsUrl (line 13) | natsUrl = "0.0.0.0"
  function GetNats (line 18) | func GetNats() (*server.Server, *nats.Conn, error) {

FILE: src/backend/interfaces/NATS/py.client/caliopen_nats/delivery.py
  class UserMessageDelivery (line 21) | class UserMessageDelivery(object):
    method __init__ (line 23) | def __init__(self, user, identity):
    method process_raw (line 29) | def process_raw(self, raw_msg_id):
  class UserMailDelivery (line 107) | class UserMailDelivery(UserMessageDelivery):
    method __init__ (line 110) | def __init__(self, user, identity):
  class UserTwitterDelivery (line 115) | class UserTwitterDelivery(UserMessageDelivery):
    method __init__ (line 118) | def __init__(self, user, identity):
  class UserMastodonDelivery (line 123) | class UserMastodonDelivery(UserMessageDelivery):
    method __init__ (line 126) | def __init__(self, user, identity):

FILE: src/backend/interfaces/NATS/py.client/caliopen_nats/listener.py
  function inbound_smtp_handler (line 21) | def inbound_smtp_handler(config):
  function inbound_twitter_handler (line 38) | def inbound_twitter_handler(config):
  function inbound_mastodon_handler (line 55) | def inbound_mastodon_handler(config):
  function contact_handler (line 72) | def contact_handler(config):
  function key_handler (line 90) | def key_handler(config):

FILE: src/backend/interfaces/NATS/py.client/caliopen_nats/subscribers.py
  class BaseHandler (line 23) | class BaseHandler(object):
    method __init__ (line 26) | def __init__(self, nats_cnx):
  class InboundEmail (line 31) | class InboundEmail(BaseHandler):
    method process_raw (line 34) | def process_raw(self, msg, payload):
    method handler (line 66) | def handler(self, msg):
  class InboundTwitter (line 80) | class InboundTwitter(BaseHandler):
    method process_raw (line 83) | def process_raw(self, msg, payload):
    method handler (line 115) | def handler(self, msg):
  class InboundMastodon (line 125) | class InboundMastodon(BaseHandler):
    method process_raw (line 128) | def process_raw(self, msg, payload):
    method handler (line 160) | def handler(self, msg):
  class ContactAction (line 170) | class ContactAction(BaseHandler):
    method process_update (line 173) | def process_update(self, msg, payload):
    method handler (line 188) | def handler(self, msg):
  class KeyAction (line 202) | class KeyAction(BaseHandler):
    method _process_key (line 205) | def _process_key(self, user, contact, key):
    method _process_results (line 218) | def _process_results(self, user, contact, results):
    method process_key_discovery (line 227) | def process_key_discovery(self, msg, payload):
    method handler (line 254) | def handler(self, msg):

FILE: src/backend/interfaces/REST/go.server/api_server.go
  type REST_API (line 34) | type REST_API struct
    method initialize (line 109) | func (server *REST_API) initialize(config APIConfig) error {
    method start (line 174) | func (server *REST_API) start() error {
    method AddHandlers (line 201) | func (server *REST_API) AddHandlers(api *gin.RouterGroup) {
  type APIConfig (line 39) | type APIConfig struct
  type BackendConfig (line 53) | type BackendConfig struct
  type BackendSettings (line 58) | type BackendSettings struct
  type IndexConfig (line 69) | type IndexConfig struct
  type IndexSettings (line 74) | type IndexSettings struct
  type CacheSettings (line 78) | type CacheSettings struct
  type NatsConfig (line 84) | type NatsConfig struct
  type NotifierConfig (line 97) | type NotifierConfig struct
  function InitializeServer (line 104) | func InitializeServer(config APIConfig) error {
  function StartServer (line 170) | func StartServer() error {

FILE: src/backend/interfaces/REST/go.server/cmd/caliopen_rest/cli_cmds/root.go
  constant __version__ (line 23) | __version__ = "0.26.1"
  function init (line 25) | func init() {

FILE: src/backend/interfaces/REST/go.server/cmd/caliopen_rest/cli_cmds/serve.go
  function init (line 34) | func init() {
  function sigHandler (line 55) | func sigHandler() {
  function API (line 85) | func API(cmd *cobra.Command, args []string) {
  function readConfig (line 103) | func readConfig(readAll bool) error {
  type CmdConfig (line 127) | type CmdConfig struct

FILE: src/backend/interfaces/REST/go.server/cmd/caliopen_rest/main.go
  function main (line 13) | func main() {

FILE: src/backend/interfaces/REST/go.server/dump_request.go
  function Dumper (line 14) | func Dumper() gin.HandlerFunc {

FILE: src/backend/interfaces/REST/go.server/errors.go
  type Errors (line 11) | type Errors
  type Error (line 13) | type Error struct
  function notImplemented (line 35) | func notImplemented(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/middlewares/authentication.go
  type ecdsaSignature (line 24) | type ecdsaSignature struct
  function getSignedQuery (line 29) | func getSignedQuery(c *gin.Context) string {
  function verifySignature (line 35) | func verifySignature(signature, query, curve string, x, y big.Int) (bool...
  function BasicAuthFromCache (line 63) | func BasicAuthFromCache(cache backends.APICache, realm string) gin.Handl...
  function kickUnauthorizedRequest (line 118) | func kickUnauthorizedRequest(c *gin.Context, realm string) {
  function BearerAuth (line 122) | func BearerAuth(r *http.Request) (username, password string, ok bool) {
  function parseBearerAuth (line 130) | func parseBearerAuth(auth string) (username, password string, ok bool) {

FILE: src/backend/interfaces/REST/go.server/middlewares/config.go
  constant RoutePrefix (line 4) | RoutePrefix     = "/api/v2"
  constant IdentitiesRoute (line 5) | IdentitiesRoute = "/identities"
  constant TagsRoute (line 6) | TagsRoute       = "/tags"
  constant ContactsRoute (line 7) | ContactsRoute   = "/contacts"
  constant DevicesRoute (line 8) | DevicesRoute    = "/devices"
  constant ImportsRoute (line 9) | ImportsRoute    = "/imports"

FILE: src/backend/interfaces/REST/go.server/middlewares/swagger.go
  constant noWritten (line 35) | noWritten     = -1
  constant defaultStatus (line 36) | defaultStatus = 200
  type routableUntypedAPI (line 39) | type routableUntypedAPI struct
    method HandlerFor (line 298) | func (r *routableUntypedAPI) HandlerFor(method, path string) (http.Han...
    method ServeErrorFor (line 309) | func (r *routableUntypedAPI) ServeErrorFor(operationID string) func(ht...
    method ConsumersFor (line 312) | func (r *routableUntypedAPI) ConsumersFor(mediaTypes []string) map[str...
    method ProducersFor (line 315) | func (r *routableUntypedAPI) ProducersFor(mediaTypes []string) map[str...
    method AuthenticatorsFor (line 318) | func (r *routableUntypedAPI) AuthenticatorsFor(schemes map[string]spec...
    method Formats (line 321) | func (r *routableUntypedAPI) Formats() strfmt.Registry {
    method DefaultProduces (line 324) | func (r *routableUntypedAPI) DefaultProduces() string {
    method DefaultConsumes (line 327) | func (r *routableUntypedAPI) DefaultConsumes() string {
  type jsonError (line 47) | type jsonError struct
  type jsonErrors (line 53) | type jsonErrors
  function InitSwaggerMiddleware (line 55) | func InitSwaggerMiddleware(swaggerFile string) (err error) {
  function SwaggerValidator (line 91) | func SwaggerValidator() gin.HandlerFunc {
  function SwaggerInboundValidation (line 99) | func SwaggerInboundValidation(ctx *gin.Context) {
  function newRoutableUntypedAPI (line 128) | func newRoutableUntypedAPI(spec *loads.Document, api *untyped.API, conte...
  function ServeError (line 165) | func ServeError(rw gin.ResponseWriter, r *http.Request, err error) {
  function errorAsJSON (line 207) | func errorAsJSON(err swgErr.Error) []byte {
  function flattenComposite (line 229) | func flattenComposite(errs *swgErr.CompositeError) *swgErr.CompositeError {
  function asHTTPCode (line 249) | func asHTTPCode(input int) int {
  function drainBody (line 261) | func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) {
  function newSecureAPI (line 277) | func newSecureAPI(ctx *middleware.Context, next http.Handler) http.Handl...

FILE: src/backend/interfaces/REST/go.server/operations/contacts/Identities.go
  function GetIdentities (line 18) | func GetIdentities(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/contacts/contacts.go
  function GetContactsList (line 25) | func GetContactsList(ctx *gin.Context) {
  function NewContact (line 95) | func NewContact(ctx *gin.Context) {
  function GetContact (line 140) | func GetContact(ctx *gin.Context) {
  function PatchContact (line 167) | func PatchContact(ctx *gin.Context) {
  function DeleteContact (line 224) | func DeleteContact(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/contacts/keys.go
  function NewPublicKey (line 25) | func NewPublicKey(ctx *gin.Context) {
  function GetPubKeys (line 116) | func GetPubKeys(ctx *gin.Context) {
  function GetPubKey (line 197) | func GetPubKey(ctx *gin.Context) {
  function PatchPubKey (line 259) | func PatchPubKey(ctx *gin.Context) {
  function DeletePubKey (line 321) | func DeletePubKey(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/devices/devices.go
  function NewDevice (line 24) | func NewDevice(ctx *gin.Context) {
  function GetDevicesList (line 84) | func GetDevicesList(ctx *gin.Context) {
  function GetDevice (line 114) | func GetDevice(ctx *gin.Context) {
  function PatchDevice (line 146) | func PatchDevice(ctx *gin.Context) {
  function DeleteDevice (line 196) | func DeleteDevice(ctx *gin.Context) {
  function Actions (line 235) | func Actions(ctx *gin.Context) {
  function ValidateDevice (line 310) | func ValidateDevice(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/discussions/discussions.go
  function GetDiscussionsList (line 20) | func GetDiscussionsList(ctx *gin.Context) {
  function GetDiscussion (line 85) | func GetDiscussion(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/helpers.go
  function GetImportanceLevel (line 11) | func GetImportanceLevel(ctx *gin.Context) (il [2]int8) {
  function GetPrivacyIndex (line 46) | func GetPrivacyIndex(ctx *gin.Context) (pi [2]int8) {
  function NormalizeUUIDstring (line 87) | func NormalizeUUIDstring(uuid_str string) (string, error) {

FILE: src/backend/interfaces/REST/go.server/operations/identities/identities.go
  function GetLocalIdentity (line 29) | func GetLocalIdentity(ctx *gin.Context) {
  function GetLocalsIdentities (line 36) | func GetLocalsIdentities(ctx *gin.Context) {
  function GetRemoteIdentities (line 53) | func GetRemoteIdentities(ctx *gin.Context) {
  function GetRemoteIdentity (line 91) | func GetRemoteIdentity(ctx *gin.Context) {
  function NewRemoteIdentity (line 135) | func NewRemoteIdentity(ctx *gin.Context) {
  function PatchRemoteIdentity (line 209) | func PatchRemoteIdentity(ctx *gin.Context) {
  function DeleteRemoteIdentity (line 274) | func DeleteRemoteIdentity(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/imports/import.go
  function ImportFile (line 20) | func ImportFile(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/messages/actions.go
  function Actions (line 19) | func Actions(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/messages/attachments.go
  function UploadAttachment (line 22) | func UploadAttachment(ctx *gin.Context) {
  function DeleteAttachment (line 62) | func DeleteAttachment(ctx *gin.Context) {
  function DownloadAttachment (line 97) | func DownloadAttachment(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/messages/messages.go
  function GetMessagesList (line 22) | func GetMessagesList(ctx *gin.Context) {
  function GetMessage (line 122) | func GetMessage(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/notifications/notifications.go
  function GetPendingNotif (line 28) | func GetPendingNotif(ctx *gin.Context) {
  function DeleteNotifications (line 161) | func DeleteNotifications(ctx *gin.Context) {
  function GetNotification (line 196) | func GetNotification(ctx *gin.Context) {
  function DeleteNotification (line 231) | func DeleteNotification(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/participants/discussion.go
  function HashUris (line 19) | func HashUris(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/participants/suggest.go
  function Suggest (line 18) | func Suggest(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/providers/providers.go
  function GetProvidersList (line 14) | func GetProvidersList(ctx *gin.Context) {
  function GetProvider (line 30) | func GetProvider(ctx *gin.Context) {
  function CallbackHandler (line 75) | func CallbackHandler(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/search.go
  function SimpleSearch (line 15) | func SimpleSearch(ctx *gin.Context) {
  function AdvancedSearch (line 133) | func AdvancedSearch(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/tags/tags.go
  function RetrieveUserTags (line 23) | func RetrieveUserTags(ctx *gin.Context) {
  function CreateTag (line 56) | func CreateTag(ctx *gin.Context) {
  function RetrieveTag (line 94) | func RetrieveTag(ctx *gin.Context) {
  function PatchTag (line 132) | func PatchTag(ctx *gin.Context) {
  function DeleteTag (line 184) | func DeleteTag(ctx *gin.Context) {
  function PatchResourceWithTags (line 217) | func PatchResourceWithTags(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/users/user.go
  function PatchUser (line 23) | func PatchUser(ctx *gin.Context) {
  function RequestPasswordReset (line 64) | func RequestPasswordReset(ctx *gin.Context) {
  function ValidatePassResetToken (line 95) | func ValidatePassResetToken(ctx *gin.Context) {
  function ResetPassword (line 120) | func ResetPassword(ctx *gin.Context) {
  function Create (line 154) | func Create(ctx *gin.Context) {
  function Delete (line 162) | func Delete(ctx *gin.Context) {
  function Get (line 229) | func Get(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/operations/users/username.go
  function IsAvailable (line 15) | func IsAvailable(ctx *gin.Context) {

FILE: src/backend/interfaces/REST/go.server/proxy.go
  function StartProxy (line 10) | func StartProxy(config ProxyConfig) {
  type ProxyConfig (line 28) | type ProxyConfig struct

FILE: src/backend/interfaces/REST/py.server/caliopen_api/__init__.py
  function main (line 15) | def main(global_config, **settings):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/base/__init__.py
  class Api (line 9) | class Api(object):
    method __init__ (line 13) | def __init__(self, context, request):
    method get_limit (line 17) | def get_limit(self):
    method get_offset (line 21) | def get_offset(self):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/base/config.py
  function swagger_error_view (line 22) | def swagger_error_view(exc, request):
  function includeme (line 27) | def includeme(config):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/base/context.py
  class DefaultContext (line 15) | class DefaultContext(object):
    method __init__ (line 23) | def __init__(self, request):
    method authenticated_user (line 29) | def authenticated_user(self):
    method __acl__ (line 40) | def __acl__(self):
    method append_acl (line 43) | def append_acl(self, role, rights):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/base/deserializer.py
  function json_deserializer (line 6) | def json_deserializer(request):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/base/errors.py
  function format_response_detail (line 54) | def format_response_detail(exc, request):
  function format_response (line 64) | def format_response(exc, request, details=None):
  function http_forbidden (line 85) | def http_forbidden(exc, request):
  function http_exception (line 101) | def http_exception(exc, request):
  function internal_server_error (line 110) | def internal_server_error(exc, request):
  function http_unprocessable_entity (line 127) | def http_unprocessable_entity(exc, request):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/base/exception.py
  class ValidationError (line 14) | class ValidationError(HTTPClientError):
  class AuthenticationError (line 30) | class AuthenticationError(HTTPClientError):
  class NotAcceptable (line 44) | class NotAcceptable(HTTPClientError):
  class ResourceNotFound (line 59) | class ResourceNotFound(HTTPClientError):
  class MethodNotAllowed (line 74) | class MethodNotAllowed(HTTPClientError):
  class MergePatchError (line 89) | class MergePatchError(HTTPClientError):
    method __init__ (line 92) | def __init__(self, error=None):
  class Unprocessable (line 114) | class Unprocessable(HTTPClientError):
  class MethodFailure (line 129) | class MethodFailure(HTTPClientError):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/base/renderer.py
  class TextPlainRenderer (line 20) | class TextPlainRenderer(object):
    method __init__ (line 22) | def __init__(self, request):
    method __call__ (line 25) | def __call__(self, value, system):
  class JSONEncoder (line 31) | class JSONEncoder(json.JSONEncoder):
    method default (line 33) | def default(self, obj):
  class JsonRenderer (line 48) | class JsonRenderer(object):
    method __init__ (line 53) | def __init__(self, _renderer_helper):
    method __call__ (line 56) | def __call__(self, data, context):
  class PartRenderer (line 66) | class PartRenderer(object):
    method __init__ (line 71) | def __init__(self, request):
    method __call__ (line 74) | def __call__(self, part, context):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/discussion/config.py
  function includeme (line 9) | def includeme(config):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/discussion/participants.py
  class ParticipantDiscussion (line 14) | class ParticipantDiscussion(Api):
    method __init__ (line 20) | def __init__(self, request):
    method collection_post (line 25) | def collection_post(self):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/message/config.py
  function includeme (line 9) | def includeme(config):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/message/message.py
  class Message (line 25) | class Message(Api):
    method __init__ (line 26) | def __init__(self, request):
    method collection_post (line 31) | def collection_post(self):
    method patch (line 52) | def patch(self):
    method delete (line 84) | def delete(self):
  class Raw (line 104) | class Raw(Api):
    method __init__ (line 107) | def __init__(self, request):
    method get (line 112) | def get(self):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/user/authentication.py
  class EcdsaSignature (line 21) | class EcdsaSignature(Sequence):
  class AuthenticatedUser (line 28) | class AuthenticatedUser(object):
    method __init__ (line 31) | def __init__(self, request):
    method _check_user (line 39) | def _check_user(self):
    method _get_il_range (line 84) | def _get_il_range(self):
    method _validate_signature (line 99) | def _validate_signature(self, request, device_id, infos):
    method _load_user (line 133) | def _load_user(self):
    method id (line 139) | def id(self):
    method username (line 144) | def username(self):
    method contact (line 149) | def contact(self):
  class AuthenticationPolicy (line 154) | class AuthenticationPolicy(object):
    method authenticated_userid (line 159) | def authenticated_userid(self, request):
    method effective_principals (line 170) | def effective_principals(self, request):
    method unauthenticated_userid (line 176) | def unauthenticated_userid(self, request):
    method remember (line 182) | def remember(self, request, principal, **kw):
    method forget (line 186) | def forget(self, request):
  class AuthorizationPolicy (line 191) | class AuthorizationPolicy(object):
    method permits (line 194) | def permits(self, context, principals, permission):
    method principals_allowed_by_permission (line 212) | def principals_allowed_by_permission(self, context, permission):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/user/config.py
  function includeme (line 11) | def includeme(config):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/user/contact.py
  class Contact (line 30) | class Contact(Api):
    method __init__ (line 33) | def __init__(self, request):
    method collection_get (line 38) | def collection_get(self):
    method get (line 56) | def get(self):
    method collection_post (line 74) | def collection_post(self):
    method patch (line 93) | def patch(self):
    method delete (line 119) | def delete(self):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/user/imports.py
  class ContactImport (line 23) | class ContactImport(Api):
    method __init__ (line 24) | def __init__(self, request):
    method collection_post (line 29) | def collection_post(self):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/user/settings.py
  class SettingsAPI (line 24) | class SettingsAPI(Api):
    method __init__ (line 27) | def __init__(self, request, context):
    method get (line 33) | def get(self):
    method patch (line 42) | def patch(self):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/user/user.py
  function get_device_sig_key (line 35) | def get_device_sig_key(user, device):
  function patch_device_key (line 46) | def patch_device_key(key, param):
  function make_user_device_tokens (line 56) | def make_user_device_tokens(request, user, device, key, ttl=86400):
  class AuthenticationAPI (line 97) | class AuthenticationAPI(Api):
    method collection_post (line 101) | def collection_post(self):
  function no_such_user (line 163) | def no_such_user(request):
  class UserAPI (line 174) | class UserAPI(Api):
    method collection_post (line 180) | def collection_post(self):
  class MeUserAPI (line 247) | class MeUserAPI(Api):
    method get (line 252) | def get(self):
  function notify_new_user (line 260) | def notify_new_user(user, config):

FILE: src/backend/interfaces/REST/py.server/caliopen_api/user/util.py
  function create_token (line 8) | def create_token(size=40):

FILE: src/backend/main/go.backends/AttachmentsInterfaces.go
  type AttachmentStorage (line 7) | type AttachmentStorage interface

FILE: src/backend/main/go.backends/CacheInterfaces.go
  type APICache (line 12) | type APICache interface
  type CacheBackend (line 32) | type CacheBackend interface

FILE: src/backend/main/go.backends/ContactsInterfaces.go
  type ContactStorage (line 13) | type ContactStorage interface
  type ContactIndex (line 24) | type ContactIndex interface

FILE: src/backend/main/go.backends/CredentialsInterfaces.go
  type CredentialsStorage (line 13) | type CredentialsStorage interface

FILE: src/backend/main/go.backends/DevicesInterfaces.go
  type DevicesStorage (line 13) | type DevicesStorage interface

FILE: src/backend/main/go.backends/DiscussionsInterface.go
  type DiscussionStorage (line 13) | type DiscussionStorage interface
  type DiscussionIndex (line 18) | type DiscussionIndex interface

FILE: src/backend/main/go.backends/IdentitiesInterface.go
  type IdentityStorage (line 14) | type IdentityStorage interface
  type IdentityStorageUpdater (line 32) | type IdentityStorageUpdater interface

FILE: src/backend/main/go.backends/KeysInterfaces.go
  type KeysStorage (line 13) | type KeysStorage interface

FILE: src/backend/main/go.backends/LDAInterfaces.go
  type LDAStore (line 14) | type LDAStore interface
  type LDAIndex (line 43) | type LDAIndex interface

FILE: src/backend/main/go.backends/MessagesInterfaces.go
  type MessageStorage (line 7) | type MessageStorage interface
  type MessageIndex (line 16) | type MessageIndex interface

FILE: src/backend/main/go.backends/NotificationsInterfaces.go
  type NotificationsStore (line 12) | type NotificationsStore interface
  type NotificationsIndex (line 24) | type NotificationsIndex interface

FILE: src/backend/main/go.backends/ProvidersInterfaces.go
  type ProviderStorage (line 12) | type ProviderStorage interface

FILE: src/backend/main/go.backends/RESTInterfaces.go
  type APIStorage (line 12) | type APIStorage interface
  type APIIndex (line 29) | type APIIndex interface

FILE: src/backend/main/go.backends/TagsInterfaces.go
  type TagsStorage (line 7) | type TagsStorage interface

FILE: src/backend/main/go.backends/UrisInterface.go
  type UrisStorage (line 7) | type UrisStorage interface

FILE: src/backend/main/go.backends/UsersInterfaces.go
  type UserStorage (line 12) | type UserStorage interface
  type UserNameStorage (line 21) | type UserNameStorage interface

FILE: src/backend/main/go.backends/backendstest/APIstore.go
  type APIStore (line 11) | type APIStore struct
    method GetSession (line 27) | func (s *APIStore) GetSession() *gocql.Session {

FILE: src/backend/main/go.backends/backendstest/Attachments.go
  type AttachmentStore (line 12) | type AttachmentStore struct
    method StoreAttachment (line 14) | func (as AttachmentStore) StoreAttachment(attachment_id string, file i...
    method GetAttachment (line 17) | func (as AttachmentStore) GetAttachment(uri string) (file io.Reader, e...
    method DeleteAttachment (line 20) | func (as AttachmentStore) DeleteAttachment(uri string) error {

FILE: src/backend/main/go.backends/backendstest/Cache.go
  type MockRedis (line 14) | type MockRedis struct
    method GetAuthToken (line 19) | func (mr *MockRedis) GetAuthToken(token string) (value *Auth_cache, er...
    method LogoutUser (line 22) | func (mr *MockRedis) LogoutUser(key string) error {
    method GetResetPasswordToken (line 25) | func (mr *MockRedis) GetResetPasswordToken(token string) (*TokenSessio...
    method GetResetPasswordSession (line 28) | func (mr *MockRedis) GetResetPasswordSession(user_id string) (*TokenSe...
    method SetResetPasswordSession (line 31) | func (mr *MockRedis) SetResetPasswordSession(user_id, reset_token stri...
    method DeleteResetPasswordSession (line 34) | func (mr *MockRedis) DeleteResetPasswordSession(user_id string) error {
    method SetOauthSession (line 37) | func (mr *MockRedis) SetOauthSession(key string, session *OauthSession...
    method GetOauthSession (line 40) | func (mr *MockRedis) GetOauthSession(key string) (*OauthSession, error) {
    method DeleteOauthSession (line 43) | func (mr *MockRedis) DeleteOauthSession(user_id string) error {
    method GetDeviceValidationSession (line 46) | func (mr *MockRedis) GetDeviceValidationSession(userId, deviceId strin...
    method GetTokenValidationSession (line 49) | func (mr *MockRedis) GetTokenValidationSession(userId, token string) (...
    method SetDeviceValidationSession (line 52) | func (mr *MockRedis) SetDeviceValidationSession(userId, deviceId, toke...
    method DeleteDeviceValidationSession (line 55) | func (mr *MockRedis) DeleteDeviceValidationSession(userId, deviceId st...
    method Set (line 61) | func (mr *MockRedis) Set(key string, value []byte, expiration time.Dur...
    method Get (line 68) | func (mr *MockRedis) Get(key string) (value []byte, err error) {
    method Del (line 77) | func (mr *MockRedis) Del(key string) error {
    method GetTTL (line 84) | func (mr *MockRedis) GetTTL(key string) (Ttl time.Duration, err error) {

FILE: src/backend/main/go.backends/backendstest/Contacts.go
  type ContactsBackend (line 12) | type ContactsBackend struct
    method CreateContact (line 22) | func (cb ContactsBackend) CreateContact(contact *Contact) error {
    method RetrieveContact (line 25) | func (cb ContactsBackend) RetrieveContact(userID, contactID string) (c...
    method RetrieveUserContactId (line 28) | func (cb ContactsBackend) RetrieveUserContactId(userID string) string {
    method UpdateContact (line 31) | func (cb ContactsBackend) UpdateContact(contact, oldContact *Contact, ...
    method DeleteContact (line 35) | func (cb ContactsBackend) DeleteContact(contact *Contact) error {
    method ContactExists (line 38) | func (cb ContactsBackend) ContactExists(userId, contactId string) bool {
    method LookupContactsByIdentifier (line 42) | func (cb ContactsBackend) LookupContactsByIdentifier(user_id, address,...
    method ContactsForParticipants (line 50) | func (cb ContactsBackend) ContactsForParticipants(userID string, parti...
  function GetContactBackend (line 16) | func GetContactBackend() ContactsBackend {
  type ContactsIndex (line 55) | type ContactsIndex struct
    method CreateContact (line 58) | func (ci ContactsIndex) CreateContact(user *UserInfo, contact *Contact...
    method UpdateContact (line 62) | func (ci ContactsIndex) UpdateContact(user *UserInfo, contact *Contact...
    method FilterContacts (line 67) | func (ci ContactsIndex) FilterContacts(search IndexSearch) (contacts [...
    method DeleteContact (line 71) | func (ci ContactsIndex) DeleteContact(user *UserInfo, contact *Contact...

FILE: src/backend/main/go.backends/backendstest/Credentials.go
  type CredentialStore (line 12) | type CredentialStore struct
    method CreateCredentials (line 14) | func (cs CredentialStore) CreateCredentials(userIdentity *UserIdentity...
    method RetrieveCredentials (line 17) | func (cs CredentialStore) RetrieveCredentials(userId, remoteId string)...
    method UpdateCredentials (line 20) | func (cs CredentialStore) UpdateCredentials(userId, remoteId string, c...
    method DeleteCredentials (line 23) | func (cs CredentialStore) DeleteCredentials(userId, remoteId string) e...

FILE: src/backend/main/go.backends/backendstest/Devices.go
  type DevicesStore (line 12) | type DevicesStore struct
    method CreateDevice (line 16) | func (ds DevicesStore) CreateDevice(device *Device) error {
    method RetrieveDevices (line 19) | func (ds DevicesStore) RetrieveDevices(user_id string) (devices []Devi...
    method RetrieveDevice (line 22) | func (ds DevicesStore) RetrieveDevice(userId, deviceId string) (device...
    method UpdateDevice (line 28) | func (ds DevicesStore) UpdateDevice(device, oldDevice *Device, modifie...
    method DeleteDevice (line 32) | func (ds DevicesStore) DeleteDevice(device *Device) error {

FILE: src/backend/main/go.backends/backendstest/Discussions.go
  type DiscussionsStore (line 12) | type DiscussionsStore struct
    method GetUserLookupHashes (line 14) | func (ds *DiscussionsStore) GetUserLookupHashes(userId UUID, kind, key...
    method UpsertDiscussionLookups (line 17) | func (ds *DiscussionsStore) UpsertDiscussionLookups(userId UUID, parti...

FILE: src/backend/main/go.backends/backendstest/Identities.go
  type IdentitiesBackend (line 14) | type IdentitiesBackend struct
    method RetrieveLocalsIdentities (line 41) | func (ib IdentitiesBackend) RetrieveLocalsIdentities(user_id string) (...
    method CreateUserIdentity (line 44) | func (ib IdentitiesBackend) CreateUserIdentity(userIdentity *UserIdent...
    method RetrieveUserIdentity (line 47) | func (ib IdentitiesBackend) RetrieveUserIdentity(userId, identityId st...
    method LookupIdentityByIdentifier (line 50) | func (ib IdentitiesBackend) LookupIdentityByIdentifier(string, ...stri...
    method LookupIdentityByType (line 53) | func (ib IdentitiesBackend) LookupIdentityByType(string, ...string) ([...
    method UpdateUserIdentity (line 56) | func (ib IdentitiesBackend) UpdateUserIdentity(userIdentity *UserIdent...
    method DeleteUserIdentity (line 59) | func (ib IdentitiesBackend) DeleteUserIdentity(userIdentity *UserIdent...
    method RetrieveRemoteIdentities (line 62) | func (ib IdentitiesBackend) RetrieveRemoteIdentities(userId string, wi...
    method RetrieveAllRemotes (line 65) | func (ib IdentitiesBackend) RetrieveAllRemotes(withCredentials bool) (...
    method UpdateRemoteInfosMap (line 68) | func (ib IdentitiesBackend) UpdateRemoteInfosMap(userId, remoteId stri...
    method RetrieveRemoteInfosMap (line 71) | func (ib IdentitiesBackend) RetrieveRemoteInfosMap(userId, remoteId st...
    method IsLocalIdentity (line 74) | func (ib IdentitiesBackend) IsLocalIdentity(userId, identityId string)...
    method IsRemoteIdentity (line 77) | func (ib IdentitiesBackend) IsRemoteIdentity(userId, identityId string...
    method Close (line 80) | func (ib IdentitiesBackend) Close() {
  function GetIdentitiesBackend (line 21) | func GetIdentitiesBackend(locals, remotes []*UserIdentity) *IdentitiesBa...
  function LocalsCount (line 84) | func LocalsCount() int {
  function RemotesCount (line 88) | func RemotesCount() int {
  function ActiveRemotesCount (line 92) | func ActiveRemotesCount() int {
  function RetrieveLocalsIdentities (line 102) | func RetrieveLocalsIdentities(user_id string) ([]UserIdentity, error) {
  function RetrieveUserIdentity (line 110) | func RetrieveUserIdentity(userId, identityId string, withCredentials boo...
  function RetrieveAllRemotes (line 135) | func RetrieveAllRemotes(withCredentials bool) (<-chan *UserIdentity, err...

FILE: src/backend/main/go.backends/backendstest/Keys.go
  type KeysStore (line 11) | type KeysStore struct
    method CreatePGPPubKey (line 13) | func (ks KeysStore) CreatePGPPubKey(pubkey *PublicKey) CaliopenError {
    method RetrieveContactPubKeys (line 16) | func (ks KeysStore) RetrieveContactPubKeys(userId, contactId string) (...
    method RetrievePubKey (line 19) | func (ks KeysStore) RetrievePubKey(userId, resourceId, keyId string) (...
    method DeletePubKey (line 22) | func (ks KeysStore) DeletePubKey(pubkey *PublicKey) CaliopenError {
    method UpdatePubKey (line 25) | func (ks KeysStore) UpdatePubKey(newPubKey, oldPubKey *PublicKey, modi...

FILE: src/backend/main/go.backends/backendstest/LDA.go
  type LDAStoreBackend (line 14) | type LDAStoreBackend struct
    method Close (line 34) | func (ldaStore *LDAStoreBackend) Close() {
    method RetrieveMessage (line 38) | func (ldaStore *LDAStoreBackend) RetrieveMessage(userId, msgId string)...
    method GetUsersForLocalMailRecipients (line 43) | func (ldaStore *LDAStoreBackend) GetUsersForLocalMailRecipients([]stri...
    method GetSettings (line 47) | func (ldaStore *LDAStoreBackend) GetSettings(userId string) (settings ...
    method CreateMessage (line 51) | func (ldaStore *LDAStoreBackend) CreateMessage(msg *Message) (err erro...
    method StoreRawMessage (line 55) | func (ldaStore *LDAStoreBackend) StoreRawMessage(msg RawMessage) (err ...
    method GetRawMessage (line 59) | func (ldaStore *LDAStoreBackend) GetRawMessage(rawMsgId string) (rawMs...
    method SetDeliveredStatus (line 63) | func (ldaStore *LDAStoreBackend) SetDeliveredStatus(raw_msg_id string,...
    method UpdateMessage (line 66) | func (ldaStore *LDAStoreBackend) UpdateMessage(msg *Message, fields ma...
    method CreateThreadLookup (line 69) | func (ldaStore *LDAStoreBackend) CreateThreadLookup(user_id, discussio...
    method SeekMessageByExternalRef (line 72) | func (ldaStore *LDAStoreBackend) SeekMessageByExternalRef(userID, exte...
    method LookupContactsByIdentifier (line 76) | func (ldaStore *LDAStoreBackend) LookupContactsByIdentifier(user_id, a...
    method GetAttachment (line 80) | func (ldaStore *LDAStoreBackend) GetAttachment(uri string) (file io.Re...
    method DeleteAttachment (line 83) | func (ldaStore *LDAStoreBackend) DeleteAttachment(uri string) error {
    method AttachmentExists (line 86) | func (ldaStore *LDAStoreBackend) AttachmentExists(uri string) bool {
    method RetrieveUserIdentity (line 90) | func (ldaStore *LDAStoreBackend) RetrieveUserIdentity(userId, identity...
    method UpdateUserIdentity (line 94) | func (ldaStore *LDAStoreBackend) UpdateUserIdentity(userIdentity *User...
    method RetrieveUser (line 97) | func (ldaStore *LDAStoreBackend) RetrieveUser(user_id string) (user *U...
    method UpdateRemoteInfosMap (line 100) | func (ldaStore *LDAStoreBackend) UpdateRemoteInfosMap(userId, remoteId...
    method RetrieveRemoteInfosMap (line 103) | func (ldaStore *LDAStoreBackend) RetrieveRemoteInfosMap(userId, remote...
    method TimestampRemoteLastCheck (line 106) | func (ldaStore *LDAStoreBackend) TimestampRemoteLastCheck(userId, remo...
    method RetrieveProvider (line 109) | func (ldaStore *LDAStoreBackend) RetrieveProvider(name, instance strin...
  type LDAIndexBackend (line 17) | type LDAIndexBackend struct
    method Close (line 113) | func (ldIndex *LDAIndexBackend) Close() {}
    method CreateMessage (line 114) | func (ldIndex *LDAIndexBackend) CreateMessage(user *UserInfo, msg *Mes...
    method UpdateMessage (line 117) | func (ldIndex *LDAIndexBackend) UpdateMessage(user *UserInfo, msg *Mes...
  function GetLDAStoreBackend (line 22) | func GetLDAStoreBackend() *LDAStoreBackend {
  function GetLDAIndexBackend (line 29) | func GetLDAIndexBackend() *LDAIndexBackend {

FILE: src/backend/main/go.backends/backendstest/Messages.go
  type MessagesBackend (line 12) | type MessagesBackend
    method RetrieveMessage (line 18) | func (mb MessagesBackend) RetrieveMessage(userId, msgId string) (msg *...
    method CreateMessage (line 32) | func (mb MessagesBackend) CreateMessage(msg *Message) error {
    method UpdateMessage (line 36) | func (mb MessagesBackend) UpdateMessage(msg *Message, fields map[strin...
    method DeleteMessage (line 40) | func (mb MessagesBackend) DeleteMessage(msg *Message) error {
    method SetMessageUnread (line 44) | func (mb MessagesBackend) SetMessageUnread(user_id, message_id string,...
    method GetRawMessage (line 48) | func (mb MessagesBackend) GetRawMessage(raw_message_id string) (raw_me...
  function GetMessagesBackend (line 14) | func GetMessagesBackend() MessagesBackend {

FILE: src/backend/main/go.backends/backendstest/Notifications.go
  type NotificationsStore (line 13) | type NotificationsStore struct
    method CreateMessage (line 20) | func (ns NotificationsStore) CreateMessage(msg *Message) error {
    method UserByUsername (line 23) | func (ns NotificationsStore) UserByUsername(username string) (user *Us...
    method RetrieveLocalsIdentities (line 26) | func (ns NotificationsStore) RetrieveLocalsIdentities(userId string) (...
    method PutNotificationInQueue (line 29) | func (ns NotificationsStore) PutNotificationInQueue(*Notification) err...
    method DeleteNotifications (line 33) | func (ns NotificationsStore) DeleteNotifications(userId string, until ...
    method NotificationsByTime (line 37) | func (ns NotificationsStore) NotificationsByTime(userId string, from, ...
    method NotificationsByID (line 41) | func (ns NotificationsStore) NotificationsByID(userId, from, to string...
    method RetrieveNotification (line 45) | func (ns NotificationsStore) RetrieveNotification(userId, notification...
    method DeleteNotification (line 49) | func (ns NotificationsStore) DeleteNotification(userId, notificationId...
  type NotificationsIndex (line 14) | type NotificationsIndex struct
    method CreateMessage (line 53) | func (ni NotificationsIndex) CreateMessage(user *UserInfo, msg *Messag...
  function GetNotificationsBackends (line 16) | func GetNotificationsBackends() (store NotificationsStore, index Notific...

FILE: src/backend/main/go.backends/backendstest/Providers.go
  type ProvidersStore (line 11) | type ProvidersStore struct
    method CreateProvider (line 13) | func (ps *ProvidersStore) CreateProvider(*Provider) CaliopenError {
    method RetrieveProvider (line 16) | func (ps *ProvidersStore) RetrieveProvider(name, instance string) (*Pr...
    method UpdateProvider (line 19) | func (ps *ProvidersStore) UpdateProvider(*Provider, map[string]interfa...
    method DeleteProvider (line 22) | func (ps *ProvidersStore) DeleteProvider(*Provider) CaliopenError {

FILE: src/backend/main/go.backends/backendstest/Tags.go
  type TagsStore (line 12) | type TagsStore struct
    method RetrieveUserTags (line 14) | func (ts TagsStore) RetrieveUserTags(user_id string) (tags []Tag, err ...
    method CreateTag (line 18) | func (ts TagsStore) CreateTag(tag *Tag) error {
    method RetrieveTag (line 22) | func (ts TagsStore) RetrieveTag(user_id, tag_id string) (tag Tag, err ...
    method UpdateTag (line 26) | func (ts TagsStore) UpdateTag(tag *Tag) error {
    method DeleteTag (line 30) | func (ts TagsStore) DeleteTag(user_id, tag_id string) error {

FILE: src/backend/main/go.backends/backendstest/UrisInterface.go
  type ParticipantStore (line 8) | type ParticipantStore struct
    method LookupHash (line 11) | func (ps *ParticipantStore) LookupHash(user_id UUID, uri string) ([]Ha...
    method CreateHashLookup (line 15) | func (ps *ParticipantStore) CreateHashLookup(lookup HashLookup) error {

FILE: src/backend/main/go.backends/backendstest/UserNames.go
  type UserNamesStore (line 12) | type UserNamesStore struct
    method UsernameIsAvailable (line 14) | func (uns UserNamesStore) UsernameIsAvailable(username string) (bool, ...
    method UserByUsername (line 17) | func (uns UserNamesStore) UserByUsername(username string) (user *User,...
  function UserByUsername (line 21) | func UserByUsername(username string) (user *User, err error) {

FILE: src/backend/main/go.backends/backendstest/Users.go
  type UsersBackend (line 12) | type UsersBackend struct
    method GetSettings (line 16) | func (ub UsersBackend) GetSettings(userID string) (settings *Settings,...
    method RetrieveUser (line 19) | func (ub UsersBackend) RetrieveUser(userID string) (user *User, err er...
    method UpdateUserPasswordHash (line 25) | func (ub UsersBackend) UpdateUserPasswordHash(user *User) error {
    method UpdateUser (line 28) | func (ub UsersBackend) UpdateUser(user *User, fields map[string]interf...
    method UserByRecoveryEmail (line 31) | func (ub UsersBackend) UserByRecoveryEmail(email string) (user *User, ...
    method DeleteUser (line 34) | func (ub UsersBackend) DeleteUser(userID string) error {
    method GetShardForUser (line 37) | func (ub UsersBackend) GetShardForUser(userID string) string {

FILE: src/backend/main/go.backends/backendstest/testdata.go
  constant DevIdoireUserId (line 16) | DevIdoireUserId = "ede04443-b60f-4869-9040-20bd6b1e33c1"
  constant EmmaTommeUserId (line 17) | EmmaTommeUserId = "7f8329c4-e220-45fc-89b2-d8535df69e83"
  constant JeanThubUserId (line 18) | JeanThubUserId  = "b26908c5-c32a-4301-8f79-80abf0d8f8fe"

FILE: src/backend/main/go.backends/cache/authentication.go
  method GetAuthToken (line 18) | func (c *Cache) GetAuthToken(key string) (value *Auth_cache, err error) {
  method LogoutUser (line 35) | func (c *Cache) LogoutUser(key string) error {

FILE: src/backend/main/go.backends/cache/cache.go
  type Cache (line 12) | type Cache struct

FILE: src/backend/main/go.backends/cache/devicevalidation.go
  constant validationPrefix (line 17) | validationPrefix    = "validationsession::"
  constant deviceValidationTTL (line 18) | deviceValidationTTL = 24
  method GetDeviceValidationSession (line 21) | func (c *Cache) GetDeviceValidationSession(userId, deviceId string) (ses...
  method GetTokenValidationSession (line 25) | func (c *Cache) GetTokenValidationSession(userId, token string) (session...
  method getValidationSession (line 29) | func (c *Cache) getValidationSession(key string) (session *TokenSession,...
  method SetDeviceValidationSession (line 48) | func (c *Cache) SetDeviceValidationSession(userId, deviceId, token strin...
  method DeleteDeviceValidationSession (line 84) | func (c *Cache) DeleteDeviceValidationSession(userId, deviceId string) e...

FILE: src/backend/main/go.backends/cache/devicevalidation_test.go
  function TestRedisBackend_SetDeviceValidationSession (line 13) | func TestRedisBackend_SetDeviceValidationSession(t *testing.T) {
  function TestRedisBackend_GetDeviceValidationSession (line 68) | func TestRedisBackend_GetDeviceValidationSession(t *testing.T) {
  function TestRedisBackend_GetTokenValidationSession (line 89) | func TestRedisBackend_GetTokenValidationSession(t *testing.T) {
  function TestRedisBackend_DeleteDeviceValidationSession (line 110) | func TestRedisBackend_DeleteDeviceValidationSession(t *testing.T) {

FILE: src/backend/main/go.backends/cache/oauthsessions.go
  constant oauthSessionPrefix (line 15) | oauthSessionPrefix = "oauthsession::"
  constant oauthSessionTTL (line 16) | oauthSessionTTL    = 10
  method GetOauthSession (line 20) | func (c *Cache) GetOauthSession(key string) (session *OauthSession, err ...
  method SetOauthSession (line 37) | func (c *Cache) SetOauthSession(key string, session *OauthSession) (err ...
  method DeleteOauthSession (line 55) | func (c *Cache) DeleteOauthSession(key string) error {

FILE: src/backend/main/go.backends/cache/passwordreset.go
  constant sessionPrefix (line 15) | sessionPrefix    = "resetsession::"
  constant resetTokenPrefix (line 16) | resetTokenPrefix = "resettoken::"
  constant resetPasswordTTL (line 17) | resetPasswordTTL = 8
  method GetResetPasswordSession (line 22) | func (c *Cache) GetResetPasswordSession(userId string) (session *TokenSe...
  method SetResetPasswordSession (line 44) | func (c *Cache) SetResetPasswordSession(userId, resetToken string) (sess...
  method setResetPasswordToken (line 76) | func (c *Cache) setResetPasswordToken(token string, session []byte, ttl ...
  method GetResetPasswordToken (line 81) | func (c *Cache) GetResetPasswordToken(token string) (session *TokenSessi...
  method DeleteResetPasswordSession (line 100) | func (c *Cache) DeleteResetPasswordSession(userId string) error {

FILE: src/backend/main/go.backends/cache/redis.go
  type redisBackend (line 15) | type redisBackend struct
    method Set (line 41) | func (rb *redisBackend) Set(key string, value []byte, ttl time.Duratio...
    method Get (line 45) | func (rb *redisBackend) Get(key string) (value []byte, err error) {
    method Del (line 49) | func (rb *redisBackend) Del(key string) error {
  function InitializeRedisBackend (line 19) | func InitializeRedisBackend(config CacheConfig) (c *Cache, err error) {
  function InitializeTestCache (line 53) | func InitializeTestCache() (c *Cache, mock *backendstest.MockRedis, err ...

FILE: src/backend/main/go.backends/index/elasticsearch/broad_search.go
  method Search (line 17) | func (es *ElasticSearchBackend) Search(search IndexSearch) (result *Inde...

FILE: src/backend/main/go.backends/index/elasticsearch/contacts.go
  method CreateContact (line 19) | func (es *ElasticSearchBackend) CreateContact(user *UserInfo, contact *C...
  method UpdateContact (line 37) | func (es *ElasticSearchBackend) UpdateContact(user *UserInfo, contact *C...
  method DeleteContact (line 61) | func (es *ElasticSearchBackend) DeleteContact(user *UserInfo, contact *C...
  method SetContactUnread (line 69) | func (es *ElasticSearchBackend) SetContactUnread(user_id, Contact_id str...
  method FilterContacts (line 73) | func (es *ElasticSearchBackend) FilterContacts(filter IndexSearch) (cont...

FILE: src/backend/main/go.backends/index/elasticsearch/discussions.go
  method GetDiscussionsList (line 20) | func (es *ElasticSearchBackend) GetDiscussionsList(filter IndexSearch, w...

FILE: src/backend/main/go.backends/index/elasticsearch/elasticsearch.go
  type ElasticSearchBackend (line 14) | type ElasticSearchBackend struct
    method initialize (line 47) | func (es *ElasticSearchBackend) initialize(config ElasticSearchConfig)...
    method Close (line 62) | func (es *ElasticSearchBackend) Close() {
  type ElasticSearchConfig (line 18) | type ElasticSearchConfig struct
  type Bucket (line 22) | type Bucket struct
  type Aggregation (line 30) | type Aggregation struct
  type DocCounter (line 36) | type DocCounter struct
  function InitializeElasticSearchIndex (line 41) | func InitializeElasticSearchIndex(config ElasticSearchConfig) (es *Elast...

FILE: src/backend/main/go.backends/index/elasticsearch/messages.go
  method CreateMessage (line 21) | func (es *ElasticSearchBackend) CreateMessage(user *objects.UserInfo, ms...
  method UpdateMessage (line 42) | func (es *ElasticSearchBackend) UpdateMessage(user *objects.UserInfo, ms...
  method SetMessageUnread (line 67) | func (es *ElasticSearchBackend) SetMessageUnread(user *objects.UserInfo,...
  method FilterMessages (line 78) | func (es *ElasticSearchBackend) FilterMessages(filter objects.IndexSearc...
  method GetMessagesRange (line 95) | func (es *ElasticSearchBackend) GetMessagesRange(filter objects.IndexSea...
  function executeMessagesQuery (line 175) | func executeMessagesQuery(search *elastic.SearchService) (messages []*ob...

FILE: src/backend/main/go.backends/index/elasticsearch/user_recipients_lookup.go
  type returnedContact (line 18) | type returnedContact struct
  type returnedParticipant (line 24) | type returnedParticipant struct
  type returnedMessage (line 31) | type returnedMessage struct
  method RecipientsSuggest (line 38) | func (es *ElasticSearchBackend) RecipientsSuggest(user *UserInfo, query_...
  function extractContactInfos (line 142) | func extractContactInfos(contact_hit *elastic.SearchHit) (suggest Recipi...
  function extractParticipantInfos (line 154) | func extractParticipantInfos(message_hit *elastic.SearchHit) (suggest Re...

FILE: src/backend/main/go.backends/store/cassandra/attachments.go
  method StoreAttachment (line 9) | func (cb *CassandraBackend) StoreAttachment(attachment_id string, file i...
  method DeleteAttachment (line 14) | func (cb *CassandraBackend) DeleteAttachment(uri string) error {
  method GetAttachment (line 18) | func (cb *CassandraBackend) GetAttachment(uri string) (file io.Reader, e...
  method AttachmentExists (line 22) | func (cb *CassandraBackend) AttachmentExists(uri string) bool {

FILE: src/backend/main/go.backends/store/cassandra/cassandra.go
  type CassandraBackend (line 17) | type CassandraBackend struct
    method initialize (line 73) | func (cb *CassandraBackend) initialize(config CassandraConfig) (err er...
    method Close (line 101) | func (cb *CassandraBackend) Close() {
    method GetSession (line 105) | func (cb *CassandraBackend) GetSession() *gocql.Session {
    method SessionQuery (line 110) | func (cb *CassandraBackend) SessionQuery(stmt string, values ...interf...
  type CassandraConfig (line 26) | type CassandraConfig struct
  type HasTable (line 37) | type HasTable interface
  constant DefaultTimeout (line 44) | DefaultTimeout = time.Second * 2
  function InitializeCassandraBackend (line 46) | func InitializeCassandraBackend(config CassandraConfig) (cb *CassandraBa...

FILE: src/backend/main/go.backends/store/cassandra/contacts.go
  method CreateContact (line 19) | func (cb *CassandraBackend) CreateContact(contact *Contact) error {
  method RetrieveContact (line 58) | func (cb *CassandraBackend) RetrieveContact(user_id, contact_id string) ...
  method RetrieveUserContactId (line 84) | func (cb *CassandraBackend) RetrieveUserContactId(userID string) string {
  method UpdateContact (line 95) | func (cb *CassandraBackend) UpdateContact(contact, oldContact *Contact, ...
  method DeleteContact (line 148) | func (cb *CassandraBackend) DeleteContact(contact *Contact) error {
  type UrisCheck (line 175) | type UrisCheck struct
  type UrisChecklist (line 180) | type UrisChecklist
  function ControlURIsUniqueness (line 184) | func ControlURIsUniqueness(cb backends.ContactStorage, contact *Contact)...
  method LookupContactsByIdentifier (line 209) | func (cb *CassandraBackend) LookupContactsByIdentifier(user_id, address,...
  method ContactExists (line 220) | func (cb *CassandraBackend) ContactExists(userId, contactId string) bool {
  method ContactsForParticipants (line 229) | func (cb *CassandraBackend) ContactsForParticipants(userID string, parti...

FILE: src/backend/main/go.backends/store/cassandra/contacts_test.go
  function TestCassandraBackend_ControlURIsUniqueness (line 10) | func TestCassandraBackend_ControlURIsUniqueness(t *testing.T) {

FILE: src/backend/main/go.backends/store/cassandra/credentials.go
  method CreateCredentials (line 15) | func (cb *CassandraBackend) CreateCredentials(userIdentity *UserIdentity...
  method RetrieveCredentials (line 28) | func (cb *CassandraBackend) RetrieveCredentials(userId, identityId strin...
  method UpdateCredentials (line 39) | func (cb *CassandraBackend) UpdateCredentials(userId, identityId string,...
  method DeleteCredentials (line 61) | func (cb *CassandraBackend) DeleteCredentials(userId, identityId string)...

FILE: src/backend/main/go.backends/store/cassandra/devices.go
  method CreateDevice (line 22) | func (cb *CassandraBackend) CreateDevice(device *Device) error {
  method RetrieveDevices (line 58) | func (cb *CassandraBackend) RetrieveDevices(userId string) (devices []De...
  method RetrieveDevice (line 81) | func (cb *CassandraBackend) RetrieveDevice(userId, deviceId string) (dev...
  method UpdateDevice (line 105) | func (cb *CassandraBackend) UpdateDevice(device, oldDevice *Device, fiel...
  method DeleteDevice (line 149) | func (cb *CassandraBackend) DeleteDevice(device *Device) error {

FILE: src/backend/main/go.backends/store/cassandra/discussions.go
  method GetUserLookupHashes (line 15) | func (cb *CassandraBackend) GetUserLookupHashes(userId UUID, kind, key s...
  method RetrieveParticipantHash (line 37) | func (cb *CassandraBackend) RetrieveParticipantHash(userId UUID, kind, h...
  method CreateParticipantHash (line 48) | func (cb *CassandraBackend) CreateParticipantHash(lookup *ParticipantHas...
  method UpsertDiscussionLookups (line 63) | func (cb *CassandraBackend) UpsertDiscussionLookups(userId UUID, partici...
  method CreateLookupsFromUris (line 76) | func (cb *CassandraBackend) CreateLookupsFromUris(userId UUID, uriHash s...

FILE: src/backend/main/go.backends/store/cassandra/emails.go
  method GetUsersForLocalMailRecipients (line 14) | func (cb *CassandraBackend) GetUsersForLocalMailRecipients(rcpts []strin...

FILE: src/backend/main/go.backends/store/cassandra/identities.go
  method RetrieveLocalsIdentities (line 19) | func (cb *CassandraBackend) RetrieveLocalsIdentities(userId string) (ide...
  method CreateUserIdentity (line 41) | func (cb *CassandraBackend) CreateUserIdentity(userIdentity *UserIdentit...
  method RetrieveUserIdentity (line 88) | func (cb *CassandraBackend) RetrieveUserIdentity(userId, identityId stri...
  method UpdateUserIdentity (line 112) | func (cb *CassandraBackend) UpdateUserIdentity(userIdentity *UserIdentit...
  method UpdateRemoteInfosMap (line 166) | func (cb *CassandraBackend) UpdateRemoteInfosMap(userId, remoteId string...
  method RetrieveRemoteInfosMap (line 182) | func (cb *CassandraBackend) RetrieveRemoteInfosMap(userId, remoteId stri...
  method RetrieveRemoteIdentities (line 196) | func (cb *CassandraBackend) RetrieveRemoteIdentities(userId string, with...
  method RetrieveAllRemotes (line 234) | func (cb *CassandraBackend) RetrieveAllRemotes(withCredentials bool) (<-...
  method DeleteUserIdentity (line 275) | func (cb *CassandraBackend) DeleteUserIdentity(userIdentity *UserIdentit...
  method LookupIdentityByIdentifier (line 294) | func (cb *CassandraBackend) LookupIdentityByIdentifier(identifier string...
  method LookupIdentityByType (line 336) | func (cb *CassandraBackend) LookupIdentityByType(identityType string, us...
  method IsLocalIdentity (line 368) | func (cb *CassandraBackend) IsLocalIdentity(userId, identityId string) b...
  method IsRemoteIdentity (line 379) | func (cb *CassandraBackend) IsRemoteIdentity(userId, identityId string) ...
  method TimestampRemoteLastCheck (line 390) | func (cb *CassandraBackend) TimestampRemoteLastCheck(userId, remoteId st...

FILE: src/backend/main/go.backends/store/cassandra/keys.go
  method CreatePGPPubKey (line 15) | func (cb *CassandraBackend) CreatePGPPubKey(pubkey *PublicKey) CaliopenE...
  method RetrieveContactPubKeys (line 59) | func (cb *CassandraBackend) RetrieveContactPubKeys(userId, contactId str...
  method RetrievePubKey (line 72) | func (cb *CassandraBackend) RetrievePubKey(userId, resourceId, keyId str...
  method UpdatePubKey (line 88) | func (cb *CassandraBackend) UpdatePubKey(newPubKey, oldPubKey *PublicKey...
  method DeletePubKey (line 118) | func (cb *CassandraBackend) DeletePubKey(pubkey *PublicKey) CaliopenError {

FILE: src/backend/main/go.backends/store/cassandra/lookups.go
  method UpdateLookups (line 16) | func (cb *CassandraBackend) UpdateLookups(new, old HasLookup, isNew bool...
  method DeleteLookups (line 38) | func (cb *CassandraBackend) DeleteLookups(obj HasLookup) error {

FILE: src/backend/main/go.backends/store/cassandra/messages.go
  method CreateMessage (line 17) | func (cb *CassandraBackend) CreateMessage(msg *Message) error {
  method RetrieveMessage (line 26) | func (cb *CassandraBackend) RetrieveMessage(user_id, msg_id string) (msg...
  method UpdateMessage (line 42) | func (cb *CassandraBackend) UpdateMessage(msg *Message, fields map[strin...
  method DeleteMessage (line 74) | func (cb *CassandraBackend) DeleteMessage(msg *Message) error {
  method SetMessageUnread (line 78) | func (cb *CassandraBackend) SetMessageUnread(user_id, message_id string,...
  method SeekMessageByExternalRef (line 85) | func (cb *CassandraBackend) SeekMessageByExternalRef(userID, externalMes...

FILE: src/backend/main/go.backends/store/cassandra/notifications.go
  method PutNotificationInQueue (line 19) | func (cb *CassandraBackend) PutNotificationInQueue(notif *Notification) ...
  method NotificationsByTime (line 46) | func (cb *CassandraBackend) NotificationsByTime(userId string, from, to ...
  method NotificationsByID (line 81) | func (cb *CassandraBackend) NotificationsByID(userID, from, to string) (...
  method DeleteNotifications (line 115) | func (cb *CassandraBackend) DeleteNotifications(userId string, until tim...
  method RetrieveNotification (line 157) | func (cb *CassandraBackend) RetrieveNotification(userID, notifID string)...
  method DeleteNotification (line 171) | func (cb *CassandraBackend) DeleteNotification(userID, notifID string) e...

FILE: src/backend/main/go.backends/store/cassandra/participant_lookup.go
  method LookupHash (line 15) | func (cb *CassandraBackend) LookupHash(user_id UUID, uri string) (hashes...
  method CreateHashLookup (line 34) | func (cb *CassandraBackend) CreateHashLookup(participant HashLookup) err...

FILE: src/backend/main/go.backends/store/cassandra/providers.go
  method CreateProvider (line 15) | func (cb *CassandraBackend) CreateProvider(provider *Provider) CaliopenE...
  method RetrieveProvider (line 32) | func (cb *CassandraBackend) RetrieveProvider(name, instance string) (pro...
  method UpdateProvider (line 44) | func (cb *CassandraBackend) UpdateProvider(provider *Provider, fields ma...
  method DeleteProvider (line 74) | func (cb *CassandraBackend) DeleteProvider(provider *Provider) CaliopenE...

FILE: src/backend/main/go.backends/store/cassandra/raw_messages.go
  method StoreRawMessage (line 16) | func (cb *CassandraBackend) StoreRawMessage(msg RawMessage) (err error) {
  method GetRawMessage (line 48) | func (cb *CassandraBackend) GetRawMessage(raw_message_id string) (messag...
  method SetDeliveredStatus (line 78) | func (cb *CassandraBackend) SetDeliveredStatus(raw_msg_id string, delive...

FILE: src/backend/main/go.backends/store/cassandra/related.go
  type relatedReference (line 18) | type relatedReference struct
  method UpdateRelated (line 27) | func (cb *CassandraBackend) UpdateRelated(new, old HasRelated, isNew boo...
  method RetrieveRelated (line 119) | func (cb *CassandraBackend) RetrieveRelated(obj HasRelated) error {
  method DeleteRelated (line 174) | func (cb *CassandraBackend) DeleteRelated(obj HasRelated) error {

FILE: src/backend/main/go.backends/store/cassandra/settings.go
  method GetSettings (line 11) | func (cb *CassandraBackend) GetSettings(user_id string) (settings *Setti...

FILE: src/backend/main/go.backends/store/cassandra/tags.go
  method RetrieveUserTags (line 15) | func (cb *CassandraBackend) RetrieveUserTags(user_id string) (tags []Tag...
  method CreateTag (line 33) | func (cb *CassandraBackend) CreateTag(tag *Tag) error {
  method RetrieveTag (line 47) | func (cb *CassandraBackend) RetrieveTag(user_id, name string) (tag Tag, ...
  method UpdateTag (line 64) | func (cb *CassandraBackend) UpdateTag(tag *Tag) error {
  method DeleteTag (line 75) | func (cb *CassandraBackend) DeleteTag(user_id, name string) error {

FILE: src/backend/main/go.backends/store/cassandra/usernames.go
  method UsernameIsAvailable (line 17) | func (cb *CassandraBackend) UsernameIsAvailable(username string) (resp b...
  method UserByUsername (line 36) | func (cb *CassandraBackend) UserByUsername(username string) (user *User,...

FILE: src/backend/main/go.backends/store/cassandra/users.go
  method RetrieveUser (line 20) | func (cb *CassandraBackend) RetrieveUser(user_id string) (user *User, er...
  method UpdateUser (line 34) | func (cb *CassandraBackend) UpdateUser(user *User, fields map[string]int...
  method UpdateUserPasswordHash (line 53) | func (cb *CassandraBackend) UpdateUserPasswordHash(user *User) error {
  method UserByRecoveryEmail (line 63) | func (cb *CassandraBackend) UserByRecoveryEmail(email string) (user *Use...
  method DeleteUser (line 73) | func (cb *CassandraBackend) DeleteUser(user_id string) error {
  method GetShardForUser (line 78) | func (cb *CassandraBackend) GetShardForUser(userID string) string {

FILE: src/backend/main/go.backends/store/object_store/attachments.go
  method PutAttachment (line 11) | func (mb *MinioBackend) PutAttachment(attchId string, attch io.Reader) (...

FILE: src/backend/main/go.backends/store/object_store/minio.go
  type MinioBackend (line 15) | type MinioBackend struct
  type OSSConfig (line 20) | type OSSConfig struct
  type ObjectsStore (line 29) | type ObjectsStore interface
  function InitializeObjectsStore (line 38) | func InitializeObjectsStore(config OSSConfig) (oss ObjectsStore, err err...

FILE: src/backend/main/go.backends/store/object_store/objects.go
  method PutObject (line 14) | func (mb *MinioBackend) PutObject(name, bucket string, object io.Reader)...
  method RemoveObject (line 25) | func (mb *MinioBackend) RemoveObject(objURI string) error {
  method GetObject (line 33) | func (mb *MinioBackend) GetObject(objURI string) (file io.Reader, err er...
  method StatObject (line 41) | func (mb *MinioBackend) StatObject(objURI string) (info minio.ObjectInfo...

FILE: src/backend/main/go.backends/store/object_store/raw_messages.go
  method PutRawMessage (line 12) | func (mb *MinioBackend) PutRawMessage(message_uuid obj.UUID, raw_email s...

FILE: src/backend/main/go.backends/store/vault/credentials.go
  type VaultCredentials (line 15) | type VaultCredentials interface
  method CreateCredentials (line 22) | func (vault *HVaultClient) CreateCredentials(userIdentity *UserIdentity,...
  method RetrieveCredentials (line 27) | func (vault *HVaultClient) RetrieveCredentials(userId, remoteId string) ...
  method UpdateCredentials (line 58) | func (vault *HVaultClient) UpdateCredentials(userId, remoteId string, cr...
  method DeleteCredentials (line 74) | func (vault *HVaultClient) DeleteCredentials(userId, remoteId string) er...

FILE: src/backend/main/go.backends/store/vault/hvault_interface.go
  type HVault (line 11) | type HVault interface

FILE: src/backend/main/go.backends/store/vault/vault_client.go
  type HVaultClient (line 16) | type HVaultClient struct
  type HVaultConfig (line 21) | type HVaultConfig struct
  constant credentialsPath (line 27) | credentialsPath = "secret/data/remoteid/credentials/%s/%s"
  constant loginPath (line 28) | loginPath = "auth/userpass/login/%s"
  function InitializeVaultBackend (line 31) | func InitializeVaultBackend(hvConf HVaultConfig) (hv HVault, err error) {

FILE: src/backend/main/go.main/caliopen.go
  type CaliopenFacilities (line 22) | type CaliopenFacilities struct
    method initialize (line 46) | func (facilities *CaliopenFacilities) initialize(config CaliopenConfig...
  function Initialize (line 41) | func Initialize(config CaliopenConfig) error {

FILE: src/backend/main/go.main/contact/contact.go
  function parseEmail (line 21) | func parseEmail(field *vcard.Field) *objects.EmailContact {
  function parsePhone (line 36) | func parsePhone(field *vcard.Field) *objects.Phone {
  function parseIm (line 49) | func parseIm(field *vcard.Field) *objects.IM {
  function readPgpKey (line 63) | func readPgpKey(pubkey []byte) (*openpgp.Entity, error) {
  function parseKey (line 81) | func parseKey(field *vcard.Field, contact *objects.Contact) (*objects.Pu...
  function parseAddress (line 106) | func parseAddress(addr *vcard.Address) *objects.PostalAddress {
  function FromVcard (line 120) | func FromVcard(user *objects.UserInfo, card vcard.Card) (*objects.Contac...

FILE: src/backend/main/go.main/contact/contact_test.go
  function TestFromVcardValid (line 87) | func TestFromVcardValid(t *testing.T) {
  function TestFromVcardInvalid (line 108) | func TestFromVcardInvalid(t *testing.T) {
  function TestFromVcardInvalidEmailFormat (line 124) | func TestFromVcardInvalidEmailFormat(t *testing.T) {

FILE: src/backend/main/go.main/contact/vcard.go
  function ParseVcardFile (line 14) | func ParseVcardFile(file io.Reader) ([]vcard.Card, error) {

FILE: src/backend/main/go.main/facilities/Messaging/facility.go
  type Facility (line 17) | type Facility interface
  type CaliopenMessaging (line 21) | type CaliopenMessaging struct
    method HandleUserAction (line 57) | func (cm *CaliopenMessaging) HandleUserAction(msg *nats.Msg) {
  function NewCaliopenMessaging (line 34) | func NewCaliopenMessaging(config CaliopenConfig, notifier *Notifications...

FILE: src/backend/main/go.main/facilities/Messaging/facility_test.go
  function TestNewCaliopenMessaging (line 16) | func TestNewCaliopenMessaging(t *testing.T) {
  function TestCaliopenMessaging_HandleUserAction (line 77) | func TestCaliopenMessaging_HandleUserAction(t *testing.T) {

FILE: src/backend/main/go.main/facilities/Notifications/batch.go
  type BatchNotification (line 13) | type BatchNotification struct
    method Add (line 36) | func (bn *BatchNotification) Add(n Notification) {
    method Save (line 47) | func (bn *BatchNotification) Save(notifier Notifiers, reference, ttl s...
    method aggregate (line 57) | func (bn *BatchNotification) aggregate(reference, ttl string) (Notific...
  constant notificationsThreshold (line 21) | notificationsThreshold = 20
  type BatchNotifier (line 23) | type BatchNotifier interface
  function NewBatch (line 28) | func NewBatch(emitter string) *BatchNotification {

FILE: src/backend/main/go.main/facilities/Notifications/batch_test.go
  function TestBatchNotification_aggregate (line 11) | func TestBatchNotification_aggregate(t *testing.T) {

FILE: src/backend/main/go.main/facilities/Notifications/email.go
  type EmailNotifiers (line 17) | type EmailNotifiers interface
  constant resetPasswordTemplate (line 22) | resetPasswordTemplate    = "email-reset-password-link.yaml"
  constant onboardingEmailTemplate (line 23) | onboardingEmailTemplate  = "email-onboarding.yaml"
  constant welcomeEmailTemplate (line 24) | welcomeEmailTemplate     = "email-welcome.yaml"
  constant resetLinkFmt (line 25) | resetLinkFmt             = "%s/auth/passwords/reset/%s"
  constant deviceValidationLinkFmt (line 26) | deviceValidationLinkFmt  = "%s/validate-device/%s"
  constant deviceValidationTemplate (line 27) | deviceValidationTemplate = "email-device-validation.yaml"
  method ByEmail (line 31) | func (N *Notifier) ByEmail(notif *Notification) CaliopenError {
  method SendEmailAdminToUser (line 106) | func (notif *Notifier) SendEmailAdminToUser(user *User, participants []P...
  method SendPasswordResetEmail (line 170) | func (notif *Notifier) SendPasswordResetEmail(user *User, session *Token...
  method SendOnboardingMails (line 214) | func (notif *Notifier) SendOnboardingMails(user *User) error {
  method SendDeviceValidationEmail (line 276) | func (notif *Notifier) SendDeviceValidationEmail(user *User, deviceName ...

FILE: src/backend/main/go.main/facilities/Notifications/facility.go
  type Notifiers (line 20) | type Notifiers interface
  type Notifier (line 30) | type Notifier struct
    method LogNotification (line 117) | func (N *Notifier) LogNotification(method string, notif *Notification) {
    method NotificationsByTime (line 132) | func (N *Notifier) NotificationsByTime(userId string, from, to time.Ti...
    method NotificationsByID (line 142) | func (N *Notifier) NotificationsByID(userId, from, to string) ([]Notif...
    method RetrieveNotification (line 152) | func (N *Notifier) RetrieveNotification(userID, notifID string) (Notif...
    method DeleteNotifications (line 160) | func (N *Notifier) DeleteNotifications(userId string, until time.Time)...
    method DeleteNotification (line 170) | func (N *Notifier) DeleteNotification(userID, notifID string) Caliopen...
  function NewNotificationsFacility (line 44) | func NewNotificationsFacility(config CaliopenConfig, queue *nats.Conn) (...

FILE: src/backend/main/go.main/facilities/Notifications/queue.go
  method ByNotifQueue (line 15) | func (N *Notifier) ByNotifQueue(notif *Notification) CaliopenError {

FILE: src/backend/main/go.main/facilities/Notifications/templating.go
  function RenderEmail (line 17) | func RenderEmail(template_path string, context map[string]interface{}) (...
  function base64encodeImgSrc (line 79) | func base64encodeImgSrc(in *pongo2.Value) *pongo2.Value {

FILE: src/backend/main/go.main/facilities/REST/RESTfacility.go
  type RESTservices (line 22) | type RESTservices interface
  type RESTfacility (line 99) | type RESTfacility struct
  function NewRESTfacility (line 110) | func NewRESTfacility(config CaliopenConfig, nats_conn *nats.Conn) (rest_...

FILE: src/backend/main/go.main/facilities/REST/attachment.go
  method AddAttachment (line 18) | func (rest *RESTfacility) AddAttachment(user *UserInfo, message_id, file...
  method DeleteAttachment (line 70) | func (rest *RESTfacility) DeleteAttachment(user *UserInfo, message_id st...
  method OpenAttachment (line 114) | func (rest *RESTfacility) OpenAttachment(user_id, message_id, attchmtInd...

FILE: src/backend/main/go.main/facilities/REST/contacts.go
  method CreateContact (line 26) | func (rest *RESTfacility) CreateContact(user *UserInfo, contact *Contact...
  method RetrieveContacts (line 59) | func (rest *RESTfacility) RetrieveContacts(filter IndexSearch) (contacts...
  method RetrieveContact (line 70) | func (rest *RESTfacility) RetrieveContact(userID, contactID string) (con...
  method LookupContactByUri (line 74) | func (rest *RESTfacility) LookupContactByUri(userID, uri string) (contac...
  method RetrieveUserContact (line 98) | func (rest *RESTfacility) RetrieveUserContact(userID string) (contact *C...
  method PatchContact (line 114) | func (rest *RESTfacility) PatchContact(user *UserInfo, patch []byte, con...
  method launchKeyDiscovery (line 182) | func (rest *RESTfacility) launchKeyDiscovery(current_contact *Contact, u...
  method UpdateContact (line 205) | func (rest *RESTfacility) UpdateContact(user *UserInfo, contact, oldCont...
  method DeleteContact (line 233) | func (rest *RESTfacility) DeleteContact(info *UserInfo, contactID string...
  method ContactExists (line 263) | func (rest *RESTfacility) ContactExists(userID, contactID string) bool {
  method ImportVcardFile (line 268) | func (rest *RESTfacility) ImportVcardFile(info *UserInfo, file io.Reader...
  function addIdentityToContact (line 311) | func addIdentityToContact(storeContact backends.ContactStorage, indexCon...

FILE: src/backend/main/go.main/facilities/REST/contacts_test.go
  function TestRESTfacility_addIdentityToContact (line 13) | func TestRESTfacility_addIdentityToContact(t *testing.T) {

FILE: src/backend/main/go.main/facilities/REST/devices.go
  method RetrieveDevices (line 29) | func (rest *RESTfacility) RetrieveDevices(userId string) (devices []Devi...
  method CreateDevice (line 37) | func (rest *RESTfacility) CreateDevice(device *Device) CaliopenError {
  method RetrieveDevice (line 59) | func (rest *RESTfacility) RetrieveDevice(userId, deviceId string) (devic...
  method PatchDevice (line 74) | func (rest *RESTfacility) PatchDevice(patch []byte, userId, deviceId str...
  method UpdateDevice (line 113) | func (rest *RESTfacility) UpdateDevice(device, oldDevice *Device, modifi...
  method DeleteDevice (line 121) | func (rest *RESTfacility) DeleteDevice(userId, deviceId string) Caliopen...
  method RequestDeviceValidation (line 137) | func (rest *RESTfacility) RequestDeviceValidation(userId, deviceId, chan...
  method ConfirmDeviceValidation (line 191) | func (rest *RESTfacility) ConfirmDeviceValidation(userId, token string) ...

FILE: src/backend/main/go.main/facilities/REST/devices_test.go
  function initRest (line 17) | func initRest() *RESTfacility {
  function TestRESTfacility_RequestDeviceValidation (line 24) | func TestRESTfacility_RequestDeviceValidation(t *testing.T) {
  function TestRESTfacility_ConfirmDeviceValidation (line 60) | func TestRESTfacility_ConfirmDeviceValidation(t *testing.T) {
  function boostrapValidationSession (line 87) | func boostrapValidationSession(userId, deviceId string) (*RESTfacility, ...

FILE: src/backend/main/go.main/facilities/REST/discussions.go
  method GetDiscussionsList (line 15) | func (rest *RESTfacility) GetDiscussionsList(user *UserInfo, ILrange, PI...
  method DiscussionMetadata (line 87) | func (rest *RESTfacility) DiscussionMetadata(user *UserInfo, discussionI...
  method ExpandDiscussionSet (line 116) | func (rest *RESTfacility) ExpandDiscussionSet(userId UUID, discussionId ...
  function mergeDiscussionAliases (line 142) | func mergeDiscussionAliases(discussions []Discussion) Discussion {

FILE: src/backend/main/go.main/facilities/REST/draft.go
  method SendDraft (line 17) | func (rest *RESTfacility) SendDraft(user_info *UserInfo, msg_id string) ...
  method ResolveSenderProtocol (line 110) | func (rest *RESTfacility) ResolveSenderProtocol(draft *Message) (string,...

FILE: src/backend/main/go.main/facilities/REST/identities.go
  method RetrieveLocalIdentities (line 20) | func (rest *RESTfacility) RetrieveLocalIdentities(user_id string) ([]Use...
  method RetrieveContactIdentities (line 27) | func (rest *RESTfacility) RetrieveContactIdentities(user_id, contact_id ...
  method RetrieveRemoteIdentities (line 84) | func (rest *RESTfacility) RetrieveRemoteIdentities(userId string, withCr...
  method CreateUserIdentity (line 102) | func (rest *RESTfacility) CreateUserIdentity(identity *UserIdentity) Cal...
  method RetrieveUserIdentity (line 162) | func (rest *RESTfacility) RetrieveUserIdentity(userId, identityId string...
  method UpdateUserIdentity (line 175) | func (rest *RESTfacility) UpdateUserIdentity(identity, oldIdentity *User...
  method PatchUserIdentity (line 183) | func (rest *RESTfacility) PatchUserIdentity(patch []byte, userId, identi...
  method DeleteUserIdentity (line 226) | func (rest *RESTfacility) DeleteUserIdentity(userId, identityId string) ...
  method IsRemoteIdentity (line 261) | func (rest *RESTfacility) IsRemoteIdentity(userId, identityId string) bo...

FILE: src/backend/main/go.main/facilities/REST/keys.go
  method CreatePGPPubKey (line 21) | func (rest *RESTfacility) CreatePGPPubKey(label string, pubkey []byte, c...
  method RetrieveContactPubKeys (line 72) | func (rest *RESTfacility) RetrieveContactPubKeys(userId, contactId strin...
  method RetrievePubKey (line 76) | func (rest *RESTfacility) RetrievePubKey(userId, resourceId, keyId strin...
  method PatchPubKey (line 84) | func (rest *RESTfacility) PatchPubKey(patch []byte, userId, resourceId, ...
  method UpdatePubKey (line 111) | func (rest *RESTfacility) UpdatePubKey(newPubKey, oldPubKey *PublicKey, ...
  method DeletePubKey (line 115) | func (rest *RESTfacility) DeletePubKey(pubKey *PublicKey) CaliopenError {

FILE: src/backend/main/go.main/facilities/REST/message.go
  method SetMessageUnread (line 12) | func (rest *RESTfacility) SetMessageUnread(user *UserInfo, message_id st...
  method GetRawMessage (line 23) | func (rest *RESTfacility) GetRawMessage(raw_message_id string) (raw_mess...
  method GetMessagesList (line 33) | func (rest *RESTfacility) GetMessagesList(filter IndexSearch) (messages ...
  method GetMessagesRange (line 64) | func (rest *RESTfacility) GetMessagesRange(filter IndexSearch) (messages...
  method GetMessage (line 94) | func (rest *RESTfacility) GetMessage(user *UserInfo, msg_id string) (msg...

FILE: src/backend/main/go.main/facilities/REST/nats.go
  method PublishOnNats (line 20) | func (rest *RESTfacility) PublishOnNats(message, topic string) error {

FILE: src/backend/main/go.main/facilities/REST/providers.go
  method RetrieveProvidersList (line 23) | func (rest *RESTfacility) RetrieveProvidersList() (providers []Provider,...
  method RetrieveRegisteredMastodon (line 34) | func (rest *RESTfacility) RetrieveRegisteredMastodon() (instances []Prov...
  method GetProviderOauthFor (line 42) | func (rest *RESTfacility) GetProviderOauthFor(userId, name, identifier s...
  method CreateTwitterIdentity (line 164) | func (rest *RESTfacility) CreateTwitterIdentity(requestToken, verifier s...
  method CreateGmailIdentity (line 271) | func (rest *RESTfacility) CreateGmailIdentity(state, code string) (remot...
  method CreateMastodonIdentity (line 395) | func (rest *RESTfacility) CreateMastodonIdentity(state, code string) (re...
  function setTwitterAuthRequestUrl (line 509) | func setTwitterAuthRequestUrl(provider *Provider, hostname string) (requ...

FILE: src/backend/main/go.main/facilities/REST/search.go
  method Search (line 11) | func (rest *RESTfacility) Search(search IndexSearch) (response *IndexRes...

FILE: src/backend/main/go.main/facilities/REST/settings.go
  method GetSettings (line 11) | func (rest *RESTfacility) GetSettings(user_id string) (settings *Setting...

FILE: src/backend/main/go.main/facilities/REST/suggest_participants.go
  method SuggestRecipients (line 16) | func (rest *RESTfacility) SuggestRecipients(user *UserInfo, query_string...

FILE: src/backend/main/go.main/facilities/REST/tags.go
  method RetrieveUserTags (line 12) | func (rest *RESTfacility) RetrieveUserTags(user_id string) (tags []Tag, ...
  method CreateTag (line 26) | func (rest *RESTfacility) CreateTag(tag *Tag) CaliopenError {
  method RetrieveTag (line 44) | func (rest *RESTfacility) RetrieveTag(user_id, tag_name string) (tag Tag...
  method PatchTag (line 56) | func (rest *RESTfacility) PatchTag(patch []byte, user_id, tag_name strin...
  method UpdateTag (line 96) | func (rest *RESTfacility) UpdateTag(tag *Tag) CaliopenError {
  method DeleteTag (line 122) | func (rest *RESTfacility) DeleteTag(user_id, tag_name string) CaliopenEr...
  method UpdateResourceTags (line 145) | func (rest *RESTfacility) UpdateResourceTags(user *UserInfo, resourceID,...
  method IsTagLabelNameUnique (line 246) | func (rest *RESTfacility) IsTagLabelNameUnique(labelname, userID string)...
  method deleteEmbeddedTagReferences (line 260) | func (rest *RESTfacility) deleteEmbeddedTagReferences(userID, tagName st...
  function utf8ToASCIILowerNoSpace (line 264) | func utf8ToASCIILowerNoSpace(s string) string {

FILE: src/backend/main/go.main/facilities/REST/username.go
  method UsernameIsAvailable (line 7) | func (rest *RESTfacility) UsernameIsAvailable(username string) (bool, er...

FILE: src/backend/main/go.main/facilities/REST/users.go
  constant changePasswordSubject (line 23) | changePasswordSubject   = "Information Caliopen : votre mot de passe a é...
  constant changePasswordBodyPlain (line 24) | changePasswordBodyPlain = `
  constant changePasswordBodyRich (line 27) | changePasswordBodyRich = changePasswordBodyPlain
  method PatchUser (line 32) | func (rest *RESTfacility) PatchUser(userId string, patch *gjson.Result, ...
  method GetUser (line 74) | func (rest *RESTfacility) GetUser(userId string) (user *User, err error) {
  function validatePasswordPatch (line 80) | func validatePasswordPatch(patch *gjson.Result) error {
  method RequestPasswordReset (line 107) | func (rest *RESTfacility) RequestPasswordReset(payload PasswordResetRequ...
  method ValidatePasswordResetToken (line 168) | func (rest *RESTfacility) ValidatePasswordResetToken(token string) (sess...
  method ResetUserPassword (line 179) | func (rest *RESTfacility) ResetUserPassword(token, new_password string, ...
  method DeleteUser (line 224) | func (rest *RESTfacility) DeleteUser(payload ActionsPayload) CaliopenErr...

FILE: src/backend/main/go.main/helpers/contact.go
  function ComputeNewTitle (line 17) | func ComputeNewTitle(c *Contact) {
  function ComputeTitle (line 44) | func ComputeTitle(c *Contact) {
  function NormalizePhoneNumbers (line 81) | func NormalizePhoneNumbers(c *Contact) {

FILE: src/backend/main/go.main/helpers/discussion.go
  function ComputeDiscussionIL (line 16) | func ComputeDiscussionIL(messagesIL []float64) float64 {

FILE: src/backend/main/go.main/helpers/discussion_test.go
  function TestComputeDiscussionIL (line 11) | func TestComputeDiscussionIL(t *testing.T) {

FILE: src/backend/main/go.main/helpers/misc.go
  function EscapeUsername (line 7) | func EscapeUsername(username string) string {

FILE: src/backend/main/go.main/helpers/netTest.go
  function init (line 35) | func init() {
  function GetTestTlsConn (line 51) | func GetTestTlsConn() *tls.Conn {
  type zeroSource (line 57) | type zeroSource struct
    method Read (line 59) | func (zeroSource) Read(b []byte) (n int, err error) {
  function fromHex (line 67) | func fromHex(s string) []byte {
  function bigFromString (line 72) | func bigFromString(s string) *big.Int {
  function allCipherSuites (line 78) | func allCipherSuites() []uint16 {

FILE: src/backend/main/go.main/helpers/patch.go
  type errHandler (line 16) | type errHandler struct
  type patch (line 20) | type patch struct
  function UpdateWithPatch (line 33) | func UpdateWithPatch(patch []byte, obj ObjectPatchable, actor Initiator)...
  function buildPatch (line 67) | func buildPatch(rawPatch []byte, dbState ObjectPatchable, actor Initiato...
  function validateCurrentState (line 106) | func validateCurrentState(patch *patch) (err error) {
  function validateActorRights (line 146) | func validateActorRights(dbState, newState interface{}, actor Initiator)...
  function canModifyProperty (line 231) | func canModifyProperty(obj interface{}, field string, actor Initiator) b...
  function ParsePatch (line 243) | func ParsePatch(json []byte) (*gjson.Result, error) {

FILE: src/backend/main/go.main/helpers/uuid.go
  constant lillian (line 17) | lillian    = 2299160
  constant unix (line 18) | unix       = 2440587
  constant epoch (line 19) | epoch      = unix - lillian
  constant g1582 (line 20) | g1582      = epoch * 86400
  constant g1582ns100 (line 21) | g1582ns100 = g1582 * 10000000
  function GetTime (line 26) | func GetTime(uuid uuid.UUID) time.Time {
  function toUnixTime (line 35) | func toUnixTime(t int64) (sec, nsec int64) {

FILE: src/backend/main/go.main/messages/messages.go
  function SanitizeMessageBodies (line 20) | func SanitizeMessageBodies(msg *Message) {
  function CaliopenPolicy (line 35) | func CaliopenPolicy() *bluemonday.Policy {
  function ExcerptMessage (line 61) | func ExcerptMessage(msg Message, length int, wordWrap, addEllipsis bool)...
  function excerptFromHMTL (line 87) | func excerptFromHMTL(source string) (excerpt string, err error) {
  function trimExcerpt (line 119) | func trimExcerpt(s string, l int, wordWrap, addEllipsis bool) string {
  function truncate_unicode (line 139) | func truncate_unicode(s string, l int) string {
  function lastIndexPunctuation (line 153) | func lastIndexPunctuation(s string) (index, width int) {
  function replaceBodyTag (line 165) | func replaceBodyTag(in string) (out string) {

FILE: src/backend/main/go.main/pi/identities.go
  function UpdatePIContactIdentity (line 13) | func UpdatePIContactIdentity(ctx context.Context, contact *Contact, iden...

FILE: src/backend/main/go.main/pi/message.go
  function ComputePIMessage (line 15) | func ComputePIMessage(message *Message) *PIMessage {

FILE: src/backend/main/go.main/users/oauth2.go
  constant CALLBACK_BASE_URI (line 18) | CALLBACK_BASE_URI  = "/api/v2/providers/%s/callback"
  constant CRED_ACCESS_TOKEN (line 19) | CRED_ACCESS_TOKEN  = "oauth2accesstoken"
  constant CRED_REFRESH_TOKEN (line 20) | CRED_REFRESH_TOKEN = "oauh2refreshtoken"
  constant CRED_TOKEN_TYPE (line 21) | CRED_TOKEN_TYPE    = "tokentype"
  constant CRED_TOKEN_EXPIRY (line 22) | CRED_TOKEN_EXPIRY  = "tokenexpiry"
  constant CRED_USERNAME (line 23) | CRED_USERNAME      = "username"
  type Oauth2Interfacer (line 26) | type Oauth2Interfacer interface
  function ValidateOauth2Credentials (line 35) | func ValidateOauth2Credentials(userIdentity *UserIdentity, interfacer Oa...
  function SetGoogleAuthRequestUrl (line 66) | func SetGoogleAuthRequestUrl(provider *Provider, hostname string) (state...
  function SetGoogleOauthConfig (line 78) | func SetGoogleOauthConfig(provider Provider, hostname string) *oauth2.Co...
  function SetMastodonOauthConfig (line 88) | func SetMastodonOauthConfig(provider Provider, hostname string) *oauth2....
  function getValidGmailAccessToken (line 106) | func getValidGmailAccessToken(uId *UserIdentity, provider Provider, host...
  function SetMastodonAuthRequestUrl (line 147) | func SetMastodonAuthRequestUrl(provider *Provider, hostname string) (sta...
  function randomState (line 159) | func randomState() string {

FILE: src/backend/main/go.main/users/password.go
  constant defaultBcryptCost (line 19) | defaultBcryptCost   = 12
  constant passwordStrengthkey (line 20) | passwordStrengthkey = "password_strength"
  function ChangeUserPassword (line 23) | func ChangeUserPassword(user *User, patch *gjson.Result, store backends....
  function ResetUserPassword (line 36) | func ResetUserPassword(user *User, new_password string, store backends.U...

FILE: src/backend/main/py.main/caliopen_main/common/core/base.py
  class BaseUserCore (line 7) | class BaseUserCore(BaseCore):
    method user (line 13) | def user(self):
    method get (line 22) | def get(cls, user, obj_id):
    method get_by_user_id (line 32) | def get_by_user_id(cls, user_id, obj_id):
    method find (line 42) | def find(cls, user, filters=None, limit=None, offset=0, count=False):
    method count (line 61) | def count(cls, user, filters=None):
    method create (line 66) | def create(cls, user, **attrs):
    method belongs_to_user (line 72) | def belongs_to_user(cls, user_id, object_id):

FILE: src/backend/main/py.main/caliopen_main/common/core/pubkey.py
  class PublicKey (line 11) | class PublicKey(BaseUserRelatedCore):
    method find (line 18) | def find(cls, user, resource_id):
    method create (line 26) | def create(cls, user, resource_id, resource_type, **kwargs):

FILE: src/backend/main/py.main/caliopen_main/common/core/related.py
  class BaseUserRelatedCore (line 11) | class BaseUserRelatedCore(BaseCore):
    method create (line 17) | def create(cls, user, resource_id, **kwargs):
    method get (line 25) | def get(cls, user, resource_id, value):
    method find (line 39) | def find(cls, user, resource_id, filters=None):
    method to_dict (line 51) | def to_dict(self):

FILE: src/backend/main/py.main/caliopen_main/common/errors.py
  class PatchUnprocessable (line 1) | class PatchUnprocessable(Exception):
    method __init__ (line 4) | def __init__(self, message=None, **kw):
  class PatchError (line 8) | class PatchError(Exception):
    method __init__ (line 11) | def __init__(self, message=None, **kw):
  class PatchConflict (line 15) | class PatchConflict(Exception):
    method __init__ (line 18) | def __init__(self, message=None, **kw):
  class ObjectInitFailed (line 22) | class ObjectInitFailed(Exception):
    method __init__ (line 25) | def __init__(self, message=None, **kw):
  class ForbiddenAction (line 29) | class ForbiddenAction(Exception):
    method __init__ (line 36) | def __init__(self, message=None, **kw):
  class DuplicateMessage (line 40) | class DuplicateMessage(Exception):
    method __init__ (line 43) | def __init__(self, message=None, **kw):

FILE: src/backend/main/py.main/caliopen_main/common/helpers/normalize.py
  function clean_email_address (line 14) | def clean_email_address(addr):
  function clean_twitter_address (line 44) | def clean_twitter_address(addr):
  function clean_mastodon_address (line 48) | def clean_mastodon_address(addr):
  function parse_mastodon_url (line 52) | def parse_mastodon_url(url):

FILE: src/backend/main/py.main/caliopen_main/common/helpers/strings.py
  function unicode_truncate (line 11) | def unicode_truncate(s, length):
  function to_utf8 (line 21) | def to_utf8(input, charset):

FILE: src/backend/main/py.main/caliopen_main/common/interfaces/IO.py
  class JsonDictIO (line 13) | class JsonDictIO(zope.interface.Interface):
    method marshall_json_dict (line 19) | def marshall_json_dict(**options):
    method unmarshall_json_dict (line 22) | def unmarshall_json_dict(**options):
  class ProtobufIO (line 26) | class ProtobufIO(zope.interface.Interface):
    method marshall_protobuf (line 29) | def marshall_protobuf(**options):
    method unmarshall_protobuf (line 32) | def unmarshall_protobuf(message, **options):
  class DictIO (line 36) | class DictIO(zope.interface.Interface):
    method marshall_dict (line 37) | def marshall_dict(**options):
    method unmarshall_dict (line 40) | def unmarshall_dict(document, **options):
  class JsonIO (line 44) | class JsonIO(zope.interface.Interface):
    method marshall_json (line 47) | def marshall_json(**options):
    method unmarshall_json (line 50) | def unmarshall_json(document, **options):

FILE: src/backend/main/py.main/caliopen_main/common/interfaces/parser.py
  class IAttachmentParser (line 8) | class IAttachmentParser(zope.interface.Interface):
  class IParticipantParser (line 20) | class IParticipantParser(zope.interface.Interface):
  class IMessageParser (line 28) | class IMessageParser(zope.interface.Interface):

FILE: src/backend/main/py.main/caliopen_main/common/interfaces/storage.py
  class DbIO (line 8) | class DbIO(zope.interface.Interface):
    method get_db (line 11) | def get_db(**options):
    method save_db (line 15) | def save_db(**options):
    method create_db (line 19) | def create_db(**options):
    method delete_db (line 23) | def delete_db(**options):
    method update_db (line 27) | def update_db(**options):
    method marshall_db (line 31) | def marshall_db(**options):
    method unmarshall_db (line 39) | def unmarshall_db(**options):
  class IndexIO (line 44) | class IndexIO(zope.interface.Interface):
    method marshall_index (line 47) | def marshall_index(**options):
    method unmarshall_index (line 51) | def unmarshall_index(**options):

FILE: src/backend/main/py.main/caliopen_main/common/objects/base.py
  class CaliopenObject (line 22) | class CaliopenObject(object):
    method __init__ (line 31) | def __init__(self, **kwargs):
    method keys (line 63) | def keys(self):
    method update_with (line 68) | def update_with(self, sibling):
  class ObjectDictifiable (line 77) | class ObjectDictifiable(CaliopenObject):
    method marshall_dict (line 81) | def marshall_dict(self, **options):
    method unmarshall_dict (line 105) | def unmarshall_dict(self, document, **options):
  class ObjectJsonDictifiable (line 129) | class ObjectJsonDictifiable(ObjectDictifiable):
    method marshall_json_dict (line 144) | def marshall_json_dict(self, **options):
    method unmarshall_json_dict (line 148) | def unmarshall_json_dict(self, document, **options):
  class ObjectStorable (line 163) | class ObjectStorable(ObjectJsonDictifiable):
    method get_db (line 173) | def get_db(self, **options):
    method save_db (line 187) | def save_db(self, **options):
    method delete_db (line 196) | def delete_db(self, **options):
    method update_db (line 205) | def update_db(self, **options):
    method marshall_db (line 216) | def marshall_db(self, **options):
    method unmarshall_db (line 258) | def unmarshall_db(self, **options):
    method set_uuid (line 267) | def set_uuid(self):
  class ObjectUser (line 271) | class ObjectUser(ObjectStorable):
    method __init__ (line 274) | def __init__(self, user=None, **params):
    method marshall_dict (line 282) | def marshall_dict(self, **options):
    method list_db (line 307) | def list_db(cls, user):
    method get_db (line 318) | def get_db(self, **options):
    method apply_patch (line 334) | def apply_patch(self, patch, **options):
    method _check_key_consistency (line 421) | def _check_key_consistency(self, current_attr, key, obj_patch_old,
  class ObjectIndexable (line 481) | class ObjectIndexable(ObjectUser):
    method get_index (line 487) | def get_index(self, **options):
    method save_index (line 504) | def save_index(self, wait_for=False, **options):
    method create_index (line 511) | def create_index(self, **options):
    method delete_index (line 517) | def delete_index(self, **options):
    method update_index (line 527) | def update_index(self, wait_for=False, **options):
    method marshall_index (line 551) | def marshall_index(self, **options):
    method unmarshall_index (line 603) | def unmarshall_index(self, **options):
    method apply_patch (line 608) | def apply_patch(self, patch, **options):
  function unmarshall_item (line 626) | def unmarshall_item(document, key, target_object, target_attr_type,

FILE: src/backend/main/py.main/caliopen_main/common/objects/tag.py
  class ResourceTag (line 17) | class ResourceTag(ObjectJsonDictifiable):

FILE: src/backend/main/py.main/caliopen_main/common/parameters/pubkey.py
  class NewPublicKey (line 14) | class NewPublicKey(Model):
    class Options (line 37) | class Options:
  class PublicKey (line 41) | class PublicKey(NewPublicKey):
    class Options (line 51) | class Options:

FILE: src/backend/main/py.main/caliopen_main/common/parameters/tag.py
  class ResourceTag (line 8) | class ResourceTag(Model):

FILE: src/backend/main/py.main/caliopen_main/common/parameters/types.py
  class InternetAddressType (line 12) | class InternetAddressType(StringType):
    method validate_email (line 16) | def validate_email(self, value, context=None):
  class PhoneNumberType (line 24) | class PhoneNumberType(StringType):
    method validate_phone (line 28) | def validate_phone(self, value, context=None):

FILE: src/backend/main/py.main/caliopen_main/common/store/pubkey.py
  class PublicKey (line 11) | class PublicKey(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/common/store/tag.py
  class ResourceTag (line 12) | class ResourceTag(BaseUserType):
  class IndexedResourceTag (line 24) | class IndexedResourceTag(InnerObjectWrapper):

FILE: src/backend/main/py.main/caliopen_main/contact/core.py
  class ContactLookup (line 26) | class ContactLookup(BaseUserCore):
  class BaseContactSubCore (line 33) | class BaseContactSubCore(BaseCore):
    method create (line 39) | def create(cls, user, contact, **kwargs):
    method get (line 46) | def get(cls, user, contact, value):
    method find (line 57) | def find(cls, user, contact, filters=None):
    method to_dict (line 66) | def to_dict(self):
  class Contact (line 71) | class Contact(BaseUserCore, MixinCoreRelation, MixinCoreNested):
    method _compute_title (line 95) | def _compute_title(cls, contact):
    method _create_lookup (line 106) | def _create_lookup(self, type, value):
    method _create_lookups (line 116) | def _create_lookups(self):
    method normalize_phones (line 127) | def normalize_phones(cls, phones):
    method create (line 138) | def create(cls, user, contact, **related):
    method lookup (line 209) | def lookup(cls, user, value):
    method delete (line 228) | def delete(self):
    method public_keys (line 234) | def public_keys(self):
    method add_organization (line 239) | def add_organization(self, organization):
    method delete_organization (line 242) | def delete_organization(self, organization_id):
    method add_address (line 245) | def add_address(self, address):
    method delete_address (line 248) | def delete_address(self, address_id):
    method add_email (line 251) | def add_email(self, email):
    method delete_email (line 254) | def delete_email(self, email_addr):
    method add_im (line 257) | def add_im(self, im):
    method delete_im (line 260) | def delete_im(self, im_addr):
    method add_phone (line 263) | def add_phone(self, phone):
    method delete_phone (line 266) | def delete_phone(self, phone_num):
    method add_social_identity (line 269) | def add_social_identity(self, identity):
    method delete_social_identity (line 272) | def delete_social_identity(self, identity_name):
    method add_public_key (line 275) | def add_public_key(self, key):
    method delete_public_key (line 279) | def delete_public_key(self, key_id):

FILE: src/backend/main/py.main/caliopen_main/contact/objects/contact.py
  class ContactLookup (line 30) | class ContactLookup(ObjectStorable):
    method __init__ (line 33) | def __init__(self):
  class Contact (line 38) | class Contact(ObjectIndexable):
    method delete (line 85) | def delete(self):
    method _compute_title (line 104) | def _compute_title(cls, contact):

FILE: src/backend/main/py.main/caliopen_main/contact/objects/email.py
  class Email (line 13) | class Email(ObjectStorable):

FILE: src/backend/main/py.main/caliopen_main/contact/objects/identity.py
  class SocialIdentity (line 17) | class SocialIdentity(ObjectIndexable):
  class ContactIdentity (line 34) | class ContactIdentity(ObjectJsonDictifiable):

FILE: src/backend/main/py.main/caliopen_main/contact/objects/im.py
  class IM (line 14) | class IM(ObjectIndexable):

FILE: src/backend/main/py.main/caliopen_main/contact/objects/organization.py
  class Organization (line 13) | class Organization(ObjectIndexable):

FILE: src/backend/main/py.main/caliopen_main/contact/objects/phone.py
  class Phone (line 20) | class Phone(ObjectIndexable):
    method normalize_number (line 37) | def normalize_number(self, number):
    method unmarshall_dict (line 46) | def unmarshall_dict(self, document, **options):

FILE: src/backend/main/py.main/caliopen_main/contact/objects/postal_address.py
  class PostalAddress (line 13) | class PostalAddress(ObjectIndexable):

FILE: src/backend/main/py.main/caliopen_main/contact/parameters.py
  class Recipient (line 31) | class Recipient(Model):
    class Options (line 38) | class Options:
  class NewOrganization (line 42) | class NewOrganization(Model):
    class Options (line 54) | class Options:
  class Organization (line 58) | class Organization(NewOrganization):
    class Options (line 66) | class Options:
  class NewPostalAddress (line 71) | class NewPostalAddress(Model):
    class Options (line 84) | class Options:
  class PostalAddress (line 88) | class PostalAddress(NewPostalAddress):
    class Options (line 95) | class Options:
  class NewEmail (line 100) | class NewEmail(Model):
    class Options (line 108) | class Options:
  class Email (line 112) | class Email(NewEmail):
    class Options (line 117) | class Options:
  class NewIM (line 122) | class NewIM(Model):
    class Options (line 131) | class Options:
  class IM (line 135) | class IM(NewIM):
    class Options (line 142) | class Options:
  class NewPhone (line 147) | class NewPhone(Model):
    class Options (line 156) | class Options:
  class Phone (line 160) | class Phone(NewPhone):
    class Options (line 167) | class Options:
  class NewSocialIdentity (line 172) | class NewSocialIdentity(Model):
    class Options (line 179) | class Options:
  class SocialIdentity (line 183) | class SocialIdentity(NewSocialIdentity):
    class Options (line 190) | class Options:
  class NewContact (line 195) | class NewContact(Model):
    class Options (line 215) | class Options:
  class Contact (line 219) | class Contact(NewContact):
    class Options (line 239) | class Options:
  class ShortContact (line 243) | class ShortContact(Model):
    class Options (line 253) | class Options:

FILE: src/backend/main/py.main/caliopen_main/contact/parsers/vcard.py
  class VcardContact (line 15) | class VcardContact(object):
    method __init__ (line 20) | def __init__(self, vcard):
    method _get_not_empty (line 25) | def _get_not_empty(self, prop):
    method __build_email (line 34) | def __build_email(self, param):
    method __parse_emails (line 45) | def __parse_emails(self):
    method __build_phone (line 50) | def __build_phone(self, param):
    method __parse_phones (line 82) | def __parse_phones(self):
    method __build_address (line 87) | def __build_address(self, param):
    method __parse_addresses (line 96) | def __parse_addresses(self):
    method __build_organization (line 101) | def __build_organization(self, param):
    method __parse_organizations (line 106) | def __parse_organizations(self):
    method __build_im (line 110) | def __build_im(self, param):
    method __parse_impps (line 121) | def __parse_impps(self):
    method __parse_social_identities (line 125) | def __parse_social_identities(self):
    method _parse (line 135) | def _parse(self):
    method serialize (line 168) | def serialize(self):
    method validate (line 174) | def validate(self):
  class VcardParser (line 179) | class VcardParser(object):
    method __init__ (line 182) | def __init__(self, f):
    method parse (line 186) | def parse(self):

FILE: src/backend/main/py.main/caliopen_main/contact/returns.py
  class ReturnContact (line 17) | class ReturnContact(ReturnCoreObject):
  class ReturnShortContact (line 23) | class ReturnShortContact(ReturnCoreObject):
  class ReturnEmail (line 29) | class ReturnEmail(ReturnCoreObject):
  class ReturnIM (line 34) | class ReturnIM(ReturnCoreObject):
  class ReturnPhone (line 39) | class ReturnPhone(ReturnCoreObject):
  class ReturnAddress (line 44) | class ReturnAddress(ReturnCoreObject):
  class ReturnSocialIdentity (line 49) | class ReturnSocialIdentity(ReturnCoreObject):
  class ReturnOrganization (line 54) | class ReturnOrganization(ReturnCoreObject):

FILE: src/backend/main/py.main/caliopen_main/contact/store/contact.py
  class Organization (line 15) | class Organization(BaseUserType):
  class PostalAddress (line 31) | class PostalAddress(BaseUserType):
  class Email (line 47) | class Email(BaseUserType):
  class IM (line 60) | class IM(BaseUserType):
  class Phone (line 74) | class Phone(BaseUserType):
  class SocialIdentity (line 88) | class SocialIdentity(BaseUserType):
  class Contact (line 100) | class Contact(BaseModel, IndexedModelMixin):
  class ContactLookup (line 131) | class ContactLookup(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/contact/store/contact_index.py
  class IndexedOrganization (line 15) | class IndexedOrganization(InnerObjectWrapper):
  class IndexedPostalAddress (line 29) | class IndexedPostalAddress(InnerObjectWrapper):
  class IndexedInternetAddress (line 43) | class IndexedInternetAddress(InnerObjectWrapper):
  class IndexedPhone (line 53) | class IndexedPhone(InnerObjectWrapper):
  class IndexedSocialIdentity (line 64) | class IndexedSocialIdentity(InnerObjectWrapper):
  class IndexedContact (line 73) | class IndexedContact(BaseIndexDocument):
    method contact_id (line 106) | def contact_id(self):
    method build_mapping (line 111) | def build_mapping(cls):

FILE: src/backend/main/py.main/caliopen_main/device/core.py
  class DeviceLocation (line 24) | class DeviceLocation(BaseUserRelatedCore):
  class DeviceLog (line 31) | class DeviceLog(BaseUserRelatedCore):
  class Device (line 38) | class Device(BaseUserCore, MixinCoreRelation, MixinCoreNested):
    method create_from_parameter (line 50) | def create_from_parameter(cls, user, param, headers):
    method create (line 91) | def create(cls, user, device, **related):
    method check_locations (line 115) | def check_locations(self, ipaddr):
    method _log_action (line 123) | def _log_action(self, ipaddr, action):
    method login (line 128) | def login(self, ipaddr):
    method logout (line 136) | def logout(self, ipaddr):

FILE: src/backend/main/py.main/caliopen_main/device/parameters.py
  class DeviceLocation (line 16) | class DeviceLocation(Model):
    class Options (line 25) | class Options:
  class NewDevice (line 30) | class NewDevice(Model):
  class Device (line 41) | class Device(NewDevice):
    class Options (line 55) | class Options:

FILE: src/backend/main/py.main/caliopen_main/device/store.py
  class DeviceLocation (line 20) | class DeviceLocation(BaseModel):
  class Device (line 30) | class Device(BaseModel):
  class DeviceConnectionLog (line 47) | class DeviceConnectionLog(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/discussion/core/discussion.py
  class Discussion (line 16) | class Discussion(ObjectUser):
    method upsert_lookups_for_participants (line 19) | def upsert_lookups_for_participants(self, participants):

FILE: src/backend/main/py.main/caliopen_main/discussion/objects/discussion.py
  class Discussion (line 12) | class Discussion(ObjectUser):
    method upsert_lookups_for_participants (line 20) | def upsert_lookups_for_participants(self, user, participants):

FILE: src/backend/main/py.main/caliopen_main/discussion/parameters/discussion.py
  class Discussion (line 14) | class Discussion(Model):
    class Options (line 34) | class Options:

FILE: src/backend/main/py.main/caliopen_main/discussion/store/discussion_index.py
  class DiscussionIndex (line 20) | class DiscussionIndex(object):
    method __init__ (line 28) | def __init__(self, id):
  class DiscussionIndexManager (line 32) | class DiscussionIndexManager(object):
    method __init__ (line 35) | def __init__(self, user):
    method _prepare_search (line 40) | def _prepare_search(self):
    method __search_ids (line 47) | def __search_ids(self, limit, offset, min_pi, max_pi, min_il, max_il):
    method get_last_message (line 74) | def get_last_message(self, discussion_id, min_il, max_il, include_draft):
    method list_discussions (line 89) | def list_discussions(self, limit=10, offset=0, min_pi=0, max_pi=0,
    method message_belongs_to (line 110) | def message_belongs_to(self, discussion_id, message_id):
    method get_by_id (line 116) | def get_by_id(self, discussion_id, min_il=0, max_il=100):
    method get_by_uris (line 136) | def get_by_uris(self, uris_hashes, min_il=0, max_il=100):

FILE: src/backend/main/py.main/caliopen_main/discussion/store/discussion_lookup.py
  class DiscussionListLookup (line 10) | class DiscussionListLookup(BaseModel):
  class DiscussionThreadLookup (line 18) | class DiscussionThreadLookup(BaseModel):
  class DiscussionLookup (line 26) | class DiscussionLookup(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/message/core/external_references.py
  class MessageExternalRefLookup (line 9) | class MessageExternalRefLookup(BaseUserCore):

FILE: src/backend/main/py.main/caliopen_main/message/core/raw.py
  class RawMessage (line 28) | class RawMessage(BaseCore):
    method create (line 39) | def create(cls, raw):
    method get (line 48) | def get(cls, raw_msg_id):
    method get_for_user (line 91) | def get_for_user(cls, user_id, raw_msg_id):
    method parse (line 106) | def parse(self):
  class UserRawLookup (line 111) | class UserRawLookup(BaseUserCore):

FILE: src/backend/main/py.main/caliopen_main/message/objects/attachment.py
  class MessageAttachment (line 12) | class MessageAttachment(ObjectJsonDictifiable):

FILE: src/backend/main/py.main/caliopen_main/message/objects/external_references.py
  class ExternalReferences (line 11) | class ExternalReferences(ObjectJsonDictifiable):

FILE: src/backend/main/py.main/caliopen_main/message/objects/message.py
  class Message (line 36) | class Message(ObjectIndexable):
    method raw (line 80) | def raw(self):
    method raw_json (line 86) | def raw_json(self):
    method external_msg_id (line 92) | def external_msg_id(self):
    method user_identity (line 98) | def user_identity(self):
    method create_draft (line 105) | def create_draft(cls, user, **params):
    method patch_draft (line 171) | def patch_draft(self, user, patch, **options):
    method unmarshall_json_dict (line 291) | def unmarshall_json_dict(self, document, **options):
    method marshall_json_dict (line 297) | def marshall_json_dict(self, **options):

FILE: src/backend/main/py.main/caliopen_main/message/parameters/attachment.py
  class Attachment (line 9) | class Attachment(Model):
    class Options (line 18) | class Options:

FILE: src/backend/main/py.main/caliopen_main/message/parameters/draft.py
  class Draft (line 22) | class Draft(NewInboundMessage):
    method validate_uuid (line 25) | def validate_uuid(self, user_id):
    method validate_consistency (line 36) | def validate_consistency(self, user, is_new):
    method _add_from_participant (line 84) | def _add_from_participant(self, user):
    method _build_participants_for_reply (line 126) | def _build_participants_for_reply(self, parent_msg, sender):
    method _build_subject_for_reply (line 158) | def _build_subject_for_reply(self, parent_msg):
    method _update_external_references (line 179) | def _update_external_references(self, user):

FILE: src/backend/main/py.main/caliopen_main/message/parameters/external_references.py
  class ExternalReferences (line 9) | class ExternalReferences(Model):
    class Options (line 14) | class Options:

FILE: src/backend/main/py.main/caliopen_main/message/parameters/message.py
  class NewMessage (line 29) | class NewMessage(Model):
    method external_msg_id (line 55) | def external_msg_id(self):
    class Options (line 59) | class Options:
    method hash_participants (line 63) | def hash_participants(self):
  class NewInboundMessage (line 68) | class NewInboundMessage(NewMessage):
  class Message (line 73) | class Message(NewInboundMessage):
    class Options (line 85) | class Options:

FILE: src/backend/main/py.main/caliopen_main/message/parsers/mail.py
  class MailAttachment (line 40) | class MailAttachment(object):
    method __init__ (line 45) | def __init__(self, part):
    method is_attachment (line 84) | def is_attachment(cls, part):
  class MailParticipant (line 112) | class MailParticipant(object):
    method __init__ (line 117) | def __init__(self, type, addr):
  class MailMessage (line 125) | class MailMessage(object):
    method __init__ (line 141) | def __init__(self, raw_data):
    method get_bodies (line 156) | def get_bodies(self):
    method subject (line 212) | def subject(self):
    method size (line 227) | def size(self):
    method external_references (line 232) | def external_references(self):
    method date (line 259) | def date(self):
    method participants (line 272) | def participants(self):
    method attachments (line 295) | def attachments(self):
    method extra_parameters (line 312) | def extra_parameters(self):
    method headers (line 324) | def headers(self):
    method external_flags (line 342) | def external_flags(self):
  function walk_with_boundary (line 363) | def walk_with_boundary(message, boundary):

FILE: src/backend/main/py.main/caliopen_main/message/parsers/mastodon.py
  class MastodonStatus (line 15) | class MastodonStatus(object):
    method __init__ (line 27) | def __init__(self, raw_data):
    method get_bodies (line 45) | def get_bodies(self):
    method subject (line 52) | def subject(self):
    method size (line 60) | def size(self):
    method date (line 65) | def date(self):
    method participants (line 69) | def participants(self):
    method external_references (line 76) | def external_references(self):
    method attachments (line 81) | def attachments(self):
    method extra_parameters (line 86) | def extra_parameters(self):
  class MastodonParticipant (line 91) | class MastodonParticipant(object):
    method __init__ (line 98) | def __init__(self, type, url):

FILE: src/backend/main/py.main/caliopen_main/message/parsers/twitter.py
  class TwitterDM (line 16) | class TwitterDM(object):
    method __init__ (line 29) | def __init__(self, raw_data):
    method get_bodies (line 45) | def get_bodies(self):
    method subject (line 49) | def subject(self):
    method size (line 57) | def size(self):
    method date (line 62) | def date(self):
    method participants (line 67) | def participants(self):
    method external_references (line 73) | def external_references(self):
    method attachments (line 77) | def attachments(self):
    method extra_parameters (line 82) | def extra_parameters(self):
  class TwitterParticipant (line 87) | class TwitterParticipant(object):
    method __init__ (line 94) | def __init__(self, type, screen_name):

FILE: src/backend/main/py.main/caliopen_main/message/store/attachment.py
  class MessageAttachment (line 9) | class MessageAttachment(BaseUserType):

FILE: src/backend/main/py.main/caliopen_main/message/store/attachment_index.py
  class IndexedMessageAttachment (line 11) | class IndexedMessageAttachment(InnerObjectWrapper):

FILE: src/backend/main/py.main/caliopen_main/message/store/external_references.py
  class ExternalReferences (line 10) | class ExternalReferences(BaseUserType):
  class MessageExternalRefLookup (line 18) | class MessageExternalRefLookup(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/message/store/external_references_index.py
  class IndexedExternalReferences (line 11) | class IndexedExternalReferences(InnerObjectWrapper):

FILE: src/backend/main/py.main/caliopen_main/message/store/message.py
  class Message (line 19) | class Message(BaseModel, IndexedModelMixin):

FILE: src/backend/main/py.main/caliopen_main/message/store/message_index.py
  class IndexedMessage (line 15) | class IndexedMessage(BaseIndexDocument):
    method message_id (line 48) | def message_id(self):
    method build_mapping (line 53) | def build_mapping(cls):

FILE: src/backend/main/py.main/caliopen_main/message/store/raw.py
  class RawMessage (line 12) | class RawMessage(BaseModel):
  class UserRawLookup (line 22) | class UserRawLookup(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/notification/core.py
  class Notification (line 12) | class Notification(BaseUserCore):
  class NotificationTtl (line 19) | class NotificationTtl(BaseCore):

FILE: src/backend/main/py.main/caliopen_main/notification/store.py
  class Notification (line 11) | class Notification(BaseModel):
  class NotificationTtl (line 32) | class NotificationTtl(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/participant/core/participant.py
  class HashLookup (line 17) | class HashLookup(BaseCore):
  class ParticipantHash (line 22) | class ParticipantHash(BaseCore):
  function hash_participants_uri (line 27) | def hash_participants_uri(participants):
  function participants_from_uris (line 50) | def participants_from_uris(user, uris, uris_hash):

FILE: src/backend/main/py.main/caliopen_main/participant/objects/participant.py
  class Participant (line 14) | class Participant(ObjectJsonDictifiable):

FILE: src/backend/main/py.main/caliopen_main/participant/parameters/participant.py
  class Participant (line 13) | class Participant(Model):
    class Options (line 21) | class Options:

FILE: src/backend/main/py.main/caliopen_main/participant/store/participant.py
  class Participant (line 8) | class Participant(BaseUserType):
  class HashLookup (line 19) | class HashLookup(BaseModel):
  class ParticipantHash (line 36) | class ParticipantHash(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/participant/store/participant_index.py
  class IndexedParticipant (line 11) | class IndexedParticipant(InnerObjectWrapper):

FILE: src/backend/main/py.main/caliopen_main/pi/objects.py
  class PIModel (line 19) | class PIModel(BaseUserType):
  class PIIndexModel (line 29) | class PIIndexModel(InnerObjectWrapper):
  class PIObject (line 39) | class PIObject(ObjectIndexable):

FILE: src/backend/main/py.main/caliopen_main/pi/parameters.py
  class PIParameter (line 13) | class PIParameter(Model):

FILE: src/backend/main/py.main/caliopen_main/protocol/core/provider.py
  class Provider (line 10) | class Provider(BaseCore):

FILE: src/backend/main/py.main/caliopen_main/protocol/store/provider.py
  class Provider (line 9) | class Provider(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/tests/parsers/test_email.py
  class TestEmailParser (line 22) | class TestEmailParser(unittest.TestCase):
    method test_simple_1 (line 24) | def test_simple_1(self):
    method test_with_name_1 (line 30) | def test_with_name_1(self):
    method test_multiple (line 36) | def test_multiple(self):
    method test_invalid_but_valid (line 45) | def test_invalid_but_valid(self):
    method test_strange_1 (line 50) | def test_strange_1(self):

FILE: src/backend/main/py.main/caliopen_main/tests/parsers/test_mail.py
  function load_mail (line 23) | def load_mail(filename):
  class TestMailFormat (line 34) | class TestMailFormat(unittest.TestCase):
    method test_signed_mail (line 37) | def test_signed_mail(self):
    method test_encrypted_mail (line 47) | def test_encrypted_mail(self):

FILE: src/backend/main/py.main/caliopen_main/tests/parsers/test_vcard.py
  function load_vcard (line 24) | def load_vcard(filename):
  function parse_vcard (line 33) | def parse_vcard(vcard):
  class TestVcardFormat (line 38) | class TestVcardFormat(unittest.TestCase):
    method test_name_vcard (line 40) | def test_name_vcard(self):
    method test_address_vcard (line 47) | def test_address_vcard(self):
    method test_email_vcard (line 54) | def test_email_vcard(self):
    method test_ims_vcard (line 61) | def test_ims_vcard(self):

FILE: src/backend/main/py.main/caliopen_main/user/core/identity.py
  class UserIdentity (line 14) | class UserIdentity(BaseUserCore):
    method get_by_identifier (line 21) | def get_by_identifier(cls, identifier, protocol, user_id):
  class IdentityLookup (line 39) | class IdentityLookup(BaseCore):
  class IdentityTypeLookup (line 46) | class IdentityTypeLookup(BaseCore):

FILE: src/backend/main/py.main/caliopen_main/user/core/setups.py
  function setup_index (line 18) | def setup_index(user):
  function setup_shard_index (line 39) | def setup_shard_index(shard):
  function setup_system_tags (line 99) | def setup_system_tags(user):
  function setup_settings (line 111) | def setup_settings(user, settings):

FILE: src/backend/main/py.main/caliopen_main/user/core/user.py
  function allocate_user_shard (line 41) | def allocate_user_shard(user_id):
  class Tag (line 50) | class Tag(BaseUserCore):
  class FilterRule (line 57) | class FilterRule(BaseUserCore):
    method create (line 64) | def create(cls, user, rule):
    method eval (line 79) | def eval(self, message):
  class ReservedName (line 107) | class ReservedName(BaseCore):
  class UserName (line 114) | class UserName(BaseCore):
  class UserRecoveryEmail (line 121) | class UserRecoveryEmail(BaseCore):
  class Settings (line 128) | class Settings(BaseUserCore):
  class User (line 138) | class User(BaseCore):
    method _check_whitelistes (line 146) | def _check_whitelistes(cls, user):
    method _check_max_users (line 159) | def _check_max_users(cls):
    method create (line 169) | def create(cls, new_user):
    method by_name (line 320) | def by_name(cls, name):
    method is_username_available (line 326) | def is_username_available(cls, username):
    method by_local_identifier (line 335) | def by_local_identifier(cls, address, protocol):
    method authenticate (line 345) | def authenticate(cls, user_name, password):
    method contact (line 362) | def contact(self):
    method tags (line 374) | def tags(self):
    method rules (line 380) | def rules(self):
    method add_local_identity (line 386) | def add_local_identity(self, address):
    method local_identities (line 431) | def local_identities(self):
    method validate_recovery_email (line 435) | def validate_recovery_email(cls, email):

FILE: src/backend/main/py.main/caliopen_main/user/helpers/mergePatch.py
  function merge_patch (line 11) | def merge_patch(target, patch):
  class MergeBatch (line 27) | class MergeBatch(object):
    method __init__ (line 31) | def __init__(self, core):
    method add_operation (line 35) | def add_operation(self, type, column, value):
    method process (line 38) | def process(self):

FILE: src/backend/main/py.main/caliopen_main/user/helpers/validators.py
  function is_valid_username (line 7) | def is_valid_username(username):
  function main (line 23) | def main():

FILE: src/backend/main/py.main/caliopen_main/user/objects/identity.py
  class Credentials (line 14) | class Credentials():
  class UserIdentity (line 18) | class UserIdentity(ObjectUser):

FILE: src/backend/main/py.main/caliopen_main/user/objects/settings.py
  class Settings (line 17) | class Settings(ObjectUser):

FILE: src/backend/main/py.main/caliopen_main/user/objects/tag.py
  class UserTag (line 15) | class UserTag(ObjectUser):
    method delete_db (line 30) | def delete_db(self):

FILE: src/backend/main/py.main/caliopen_main/user/parameters/identity.py
  class NewUserIdentity (line 15) | class NewUserIdentity(Model):
  class UserIdentity (line 25) | class UserIdentity(NewUserIdentity):

FILE: src/backend/main/py.main/caliopen_main/user/parameters/settings.py
  class Settings (line 16) | class Settings(Model):

FILE: src/backend/main/py.main/caliopen_main/user/parameters/tag.py
  class NewUserTag (line 10) | class NewUserTag(Model):
    class Option (line 16) | class Option:
  class UserTag (line 21) | class UserTag(NewUserTag):
  class ImportedTag (line 28) | class ImportedTag(Model):
    class Option (line 36) | class Option:

FILE: src/backend/main/py.main/caliopen_main/user/parameters/user.py
  class NewUser (line 17) | class NewUser(Model):
    class Options (line 33) | class Options:
  class User (line 37) | class User(NewUser):
    class Options (line 50) | class Options:
  class NewRule (line 55) | class NewRule(Model):
    class Options (line 64) | class Options:

FILE: src/backend/main/py.main/caliopen_main/user/returns/user.py
  class ReturnUser (line 12) | class ReturnUser(ReturnCoreObject):
  class ReturnUserIdentity (line 19) | class ReturnUserIdentity(ReturnCoreObject):

FILE: src/backend/main/py.main/caliopen_main/user/store/identity.py
  class UserIdentity (line 15) | class UserIdentity(BaseModel):
  class IdentityLookup (line 30) | class IdentityLookup(BaseModel):
  class IdentityTypeLookup (line 39) | class IdentityTypeLookup(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/user/store/tag.py
  class UserTag (line 10) | class UserTag(BaseModel):

FILE: src/backend/main/py.main/caliopen_main/user/store/user.py
  class UserName (line 16) | class UserName(BaseModel):
  class UserRecoveryEmail (line 23) | class UserRecoveryEmail(BaseModel):
  class ReservedName (line 30) | class ReservedName(BaseModel):
  class User (line 36) | class User(BaseModel):
  class FilterRule (line 56) | class FilterRule(BaseModel):
  class Settings (line 68) | class Settings(BaseModel):
  class IndexUser (line 82) | class IndexUser(object):

FILE: src/backend/main/py.main/caliopen_main/user/store/user_index.py
  class IndexedUser (line 13) | class IndexedUser(BaseIndexDocument):
  class IndexedIdentity (line 22) | class IndexedIdentity(InnerObjectWrapper):

FILE: src/backend/main/py.storage/caliopen_storage/config.py
  class Configuration (line 14) | class Configuration(object):
    method __init__ (line 21) | def __init__(self, name):
    method load (line 25) | def load(cls, filename, name=None):
    method configuration (line 39) | def configuration(self):
    method get (line 46) | def get(self, key, default=None, separator='.'):

FILE: src/backend/main/py.storage/caliopen_storage/core/base.py
  class CoreMetaClass (line 19) | class CoreMetaClass(type):
    method __init__ (line 27) | def __init__(cls, name, bases, namespace):
  class BaseCore (line 36) | class BaseCore(object):
    method __init__ (line 44) | def __init__(self, model):
    method create (line 49) | def create(cls, **attrs):
    method get (line 55) | def get(cls, key):
    method save (line 63) | def save(self):
    method delete (line 67) | def delete(self):
    method __getattr__ (line 72) | def __getattr__(self, attr):
    method get_id (line 84) | def get_id(self):
    method find (line 89) | def find(cls, **kwargs):
    method count (line 104) | def count(cls, **kwargs):

FILE: src/backend/main/py.storage/caliopen_storage/core/mixin.py
  class MixinCoreRelation (line 12) | class MixinCoreRelation(object):
    method _expand_relation (line 16) | def _expand_relation(self, reltype):
    method _get_relation (line 21) | def _get_relation(self, reltype, id):
    method _add_relation (line 29) | def _add_relation(self, reltype, param):
    method _delete_relation (line 65) | def _delete_relation(self, reltype, id):
    method _add_relation_index (line 89) | def _add_relation_index(self, reltype, attrs):
    method _delete_relation_index (line 99) | def _delete_relation_index(self, reltype, key, id):
  class MixinCoreNested (line 118) | class MixinCoreNested(object):
    method _add_nested (line 122) | def _add_nested(self, column, nested):
    method _delete_nested (line 145) | def _delete_nested(self, column, nested_id):
    method create_nested (line 162) | def create_nested(cls, values, kls):

FILE: src/backend/main/py.storage/caliopen_storage/exception.py
  class NotFound (line 7) | class NotFound(Exception):
  class CredentialException (line 13) | class CredentialException(Exception):
  class DuplicateObject (line 19) | class DuplicateObject(Exception):

FILE: src/backend/main/py.storage/caliopen_storage/helpers/connection.py
  function connect_storage (line 9) | def connect_storage():
  function get_index_connection (line 26) | def get_index_connection():

FILE: src/backend/main/py.storage/caliopen_storage/helpers/json.py
  class JSONEncoder (line 15) | class JSONEncoder(json.JSONEncoder):
    method default (line 20) | def default(self, obj):
  function to_json (line 31) | def to_json(data):
  function RFC3339Milli (line 36) | def RFC3339Milli(value):

FILE: src/backend/main/py.storage/caliopen_storage/parameters.py
  class BaseReturnObject (line 14) | class BaseReturnObject(object):
  class ReturnCoreObject (line 22) | class ReturnCoreObject(BaseReturnObject):
    method _build_sub_core (line 37) | def _build_sub_core(cls, core):
    method build (line 56) | def build(cls, core):
  class ReturnIndexObject (line 94) | class ReturnIndexObject(BaseReturnObject):
    method build (line 109) | def build(cls, entry):

FILE: src/backend/main/py.storage/caliopen_storage/store/mixin.py
  function get_user_index (line 11) | def get_user_index(user_id):
  class IndexedModelMixin (line 18) | class IndexedModelMixin(object):
    method __process_udt (line 21) | def __process_udt(self, column, idx):
    method _process_column (line 45) | def _process_column(self, column, idx):
    method create_index (line 66) | def create_index(self, **extras):
    method update_index (line 89) | def update_index(self, object_id, changed_columns):
    method search (line 119) | def search(cls, user, limit=None, offset=0,

FILE: src/backend/main/py.storage/caliopen_storage/store/model.py
  class BaseModel (line 19) | class BaseModel(Model):
    method create (line 27) | def create(cls, **kwargs):
    method get (line 38) | def get(cls, **kwargs):
    method filter (line 48) | def filter(cls, **kwargs):
    method all (line 53) | def all(cls):
  class BaseIndexDocument (line 58) | class BaseIndexDocument(DocType):
    method client (line 65) | def client(cls):
    method create_mapping (line 70) | def create_mapping(cls, index_name):
  class BaseUserType (line 84) | class BaseUserType(UserType):
    method to_dict (line 87) | def to_dict(self):

FILE: src/backend/protocols/go.imap/cmd/imapctl/cli_cmds/addremote.go
  type remoteId (line 28) | type remoteId struct
  function init (line 40) | func init() {
  function addRemote (line 55) | func addRemote(cmd *cobra.Command, args []string) {

FILE: src/backend/protocols/go.imap/cmd/imapctl/cli_cmds/fullfetch.go
  function init (line 29) | func init() {
  function fullFetch (line 43) | func fullFetch(cmd *cobra.Command, args []string) {

FILE: src/backend/protocols/go.imap/cmd/imapctl/cli_cmds/root.go
  constant __version__ (line 30) | __version__ = "0.1.0"
  type CmdConfig (line 32) | type CmdConfig
  function init (line 34) | func init() {
  function initConfig (line 72) | func initConfig() {

FILE: src/backend/protocols/go.imap/cmd/imapctl/cli_cmds/syncremote.go
  function init (line 29) | func init() {
  function syncRemote (line 38) | func syncRemote(cmd *cobra.Command, args []string) {

FILE: src/backend/protocols/go.imap/cmd/imapctl/main.go
  function main (line 15) | func main() {

FILE: src/backend/protocols/go.imap/cmd/imapworker/cli_cmds/root.go
  constant __version__ (line 25) | __version__ = "0.23.0"
  function init (line 27) | func init() {

FILE: src/backend/protocols/go.imap/cmd/imapworker/cli_cmds/start.go
  constant shutdownTimeout (line 40) | shutdownTimeout = 3
  function init (line 43) | func init() {
  function sigHandler (line 56) | func sigHandler(workers []*imapWorker.Worker) {
  function start (line 97) | func start(cmd *cobra.Command, args []string) {
  type CmdConfig (line 131) | type CmdConfig
  function readConfig (line 134) | func readConfig(config *CmdConfig) error {
  function randomIdentifier (line 157) | func randomIdentifier() string {

FILE: src/backend/protocols/go.imap/cmd/imapworker/main.go
  function main (line 15) | func main() {

FILE: src/backend/protocols/go.imap/config.go
  type WorkerConfig (line 15) | type WorkerConfig struct
  constant syncingTimeout (line 30) | syncingTimeout    = 24
  constant failuresThreshold (line 31) | failuresThreshold = 72
  constant pollThrottling (line 32) | pollThrottling    = 10 * time.Second

FILE: src/backend/protocols/go.imap/fetcher.go
  type Fetcher (line 23) | type Fetcher struct
    method SyncRemoteWithLocal (line 55) | func (f *Fetcher) SyncRemoteWithLocal(order IMAPorder) error {
    method FetchRemoteToLocal (line 167) | func (f *Fetcher) FetchRemoteToLocal(order IMAPorder) error {
    method fetchMails (line 201) | func (f *Fetcher) fetchMails(userIdentity *UserIdentity, box *imapBox,...
    method syncMails (line 240) | func (f *Fetcher) syncMails(userIdentity *UserIdentity, box *imapBox, ...
    method handleFetchFailure (line 284) | func (f *Fetcher) handleFetchFailure(userIdentity *UserIdentity, err C...
    method disableRemoteIdentity (line 334) | func (f *Fetcher) disableRemoteIdentity(userIdentity *UserIdentity) {
    method emitNotification (line 358) | func (f Fetcher) emitNotification() {
    method GetProviders (line 364) | func (f *Fetcher) GetProviders() map[string]Provider {
    method GetHostname (line 368) | func (f *Fetcher) GetHostname() string {
    method GetIdentityStore (line 373) | func (f *Fetcher) GetIdentityStore() backends.IdentityStorageUpdater {
  type imapBox (line 29) | type imapBox struct
  constant lastErrorKey (line 37) | lastErrorKey      = "lastFetchError"
  constant dateFirstErrorKey (line 38) | dateFirstErrorKey = "firstErrorDate"
  constant dateLastErrorKey (line 39) | dateLastErrorKey  = "lastErrorDate"
  constant errorsCountKey (line 40) | errorsCountKey    = "errorsCount"

FILE: src/backend/protocols/go.imap/imap.go
  type ImapFetcherHeaders (line 27) | type ImapFetcherHeaders
  constant gmail_msgid (line 31) | gmail_msgid  = "X-GM-MSGID"
  constant gmail_labels (line 32) | gmail_labels = "X-GM-LABELS"
  function init (line 37) | func init() {
  function imapLogin (line 48) | func imapLogin(rId *UserIdentity) (tlsConn *tls.Conn, imapClient *client...
  function syncMailbox (line 123) | func syncMailbox(ibox *imapBox, imapClient *client.Client, provider Prov...
  function fetchMailbox (line 160) | func fetchMailbox(ibox *imapBox, imapClient *client.Client, provider Pro...
  function MarshalImap (line 181) | func MarshalImap(message *imap.Message, xHeaders ImapFetcherHeaders) (ma...
  function buildXheaders (line 208) | func buildXheaders(tlsConn *tls.Conn, rId *UserIdentity, box *imapBox, m...
  function fetch (line 261) | func fetch(imapClient *client.Client, provider Provider, from, to uint32...
  function uploadSentMessage (line 286) | func uploadSentMessage(imapClient *client.Client, mail string, date time...

FILE: src/backend/protocols/go.imap/imap_test.go
  function Test_buildXheaders (line 24) | func Test_buildXheaders(t *testing.T) {
  function TestMarshalImap (line 166) | func TestMarshalImap(t *testing.T) {

FILE: src/backend/protocols/go.imap/lda.go
  type Lda (line 20) | type Lda struct
    method shutdown (line 39) | func (lda *Lda) shutdown() error {
    method deliverMail (line 44) | func (lda *Lda) deliverMail(mail *Email, userId, identityID string, ba...
  function NewLda (line 27) | func NewLda(config WorkerConfig) (*Lda, error) {

FILE: src/backend/protocols/go.imap/sender.go
  type Sender (line 21) | type Sender struct
    method SendDraft (line 41) | func (s *Sender) SendDraft(msg *nats.Msg) {
    method natsReplyError (line 113) | func (s *Sender) natsReplyError(msg *nats.Msg, err error) {
    method UploadSentMessageToRemote (line 125) | func (s *Sender) UploadSentMessageToRemote(userIdentity *UserIdentity,...
    method GetProviders (line 150) | func (s *Sender) GetProviders() map[string]Provider {
    method GetHostname (line 154) | func (s *Sender) GetHostname() string {
    method GetIdentityStore (line 158) | func (s *Sender) GetIdentityStore() backends.IdentityStorageUpdater {

FILE: src/backend/protocols/go.imap/sender_test.go
  constant replyErrorTopic (line 19) | replyErrorTopic = "testReplyError"
  function initTestSender (line 22) | func initTestSender() (sender *Sender, natsServer *server.Server, err er...
  function TestSender_SendDraft (line 36) | func TestSender_SendDraft(t *testing.T) {

FILE: src/backend/protocols/go.imap/worker.go
  type Worker (line 22) | type Worker struct
    method Start (line 99) | func (worker *Worker) Start(throttling ...time.Duration) error {
    method Stop (line 138) | func (worker *Worker) Stop() {
    method natsMsgHandler (line 151) | func (worker *Worker) natsMsgHandler(msg *nats.Msg) {
  constant noPendingJobErr (line 33) | noPendingJobErr = "no pending job"
  constant needJobOrderStr (line 34) | needJobOrderStr = `{"worker":"%s","order":{"order":"need_job"}}`
  function NewWorker (line 38) | func NewWorker(config WorkerConfig, id string) (worker *Worker, err erro...

FILE: src/backend/protocols/go.imap/worker_test.go
  constant natsUrl (line 22) | natsUrl = "0.0.0.0"
  function newWorkerTest (line 25) | func newWorkerTest() (worker *Worker, natsServer *server.Server, err err...
  function TestWorker_StartAndStop (line 71) | func TestWorker_StartAndStop(t *testing.T) {
  function TestWorker_natsMsgHandler (line 128) | func TestWorker_natsMsgHandler(t *testing.T) {

FILE: src/backend/protocols/go.mastodon/account.go
  type AccountHandler (line 25) | type AccountHandler struct
    method Start (line 123) | func (worker *AccountHandler) Start() {
    method Stop (line 169) | func (worker *AccountHandler) Stop() {
    method PollDM (line 180) | func (worker *AccountHandler) PollDM() {
    method dmNotSeen (line 284) 
Copy disabled (too large) Download .json
Condensed preview — 2425 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (12,183K chars).
[
  {
    "path": ".drone.yml",
    "chars": 12753,
    "preview": "workspace:\n  base: /srv\n  path: caliopen\n\nclone:\n  git:\n    image: plugins/git\n    depth: 10\n    recursive: false\n\npipel"
  },
  {
    "path": ".git-crypt/.gitattributes",
    "chars": 165,
    "preview": "# Do not edit this file.  To specify the files to encrypt, create your own\n# .gitattributes file in the directory where "
  },
  {
    "path": ".gitattributes",
    "chars": 67,
    "preview": "devtools/kubernetes/secrets/*.yaml filter=git-crypt diff=git-crypt\n"
  },
  {
    "path": ".gitignore",
    "chars": 2433,
    "preview": "# Created by .ignore support plugin (hsz.mobi)\n### JetBrains template\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpSt"
  },
  {
    "path": ".travis.yml",
    "chars": 611,
    "preview": "sudo: required\nservices:\n- docker\nenv:\n  COMPOSE_VERSION: 1.9.0\nlanguage: node_js\nnode_js:\n- '8'\ncache:\n  - yarn\ngit:\n  "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 24394,
    "preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1866,
    "preview": "# Contributing\n\nFirst of all, thank you for contributing, you are awesome!\n\n- Report a bug or post a feature request: ht"
  },
  {
    "path": "LICENSE",
    "chars": 34520,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "README.md",
    "chars": 932,
    "preview": "# Caliopen Messaging Platform\n\n[![Build Status](https://travis-ci.org/CaliOpen/Caliopen.svg)](https://travis-ci.org/Cali"
  },
  {
    "path": "devtools/ES_queries/Recipient_suggest.json",
    "chars": 2019,
    "preview": "{\n  \"query\": {\n    \"bool\": {\n      \"should\": [\n        {\n          \"nested\": {\n            \"path\": \"participants\",\n     "
  },
  {
    "path": "devtools/Vagrantfile",
    "chars": 1056,
    "preview": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n# All Vagrant configuration is done below. The \"2\" in Vagrant.configure\n# conf"
  },
  {
    "path": "devtools/api-mock/README.md",
    "chars": 996,
    "preview": "# API mock\n\nThe purpose of this package is to mock the whole API using [bouchon][bouchon], it uses redux to\ncollect and "
  },
  {
    "path": "devtools/api-mock/all.fixture.js",
    "chars": 651,
    "preview": "require('babel-core/register');\nrequire('babel-polyfill');\n\nmodule.exports = {\n  default: [\n    require('./authenticatio"
  },
  {
    "path": "devtools/api-mock/authentications/data.json",
    "chars": 383,
    "preview": "{\n\t\"tokens\": {\n\t\t\"access_token\": \"de85ce575fe7f6262e0cd11582ff33ee848f1027\",\n\t\t\"expires_at\": \"2017-03-07T13:37:39.280870"
  },
  {
    "path": "devtools/api-mock/authentications/index.js",
    "chars": 798,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { actions as devicesAction, selectors as devicesSelector "
  },
  {
    "path": "devtools/api-mock/bin/start",
    "chars": 405,
    "preview": "#!/bin/bash\n\n# Generate swagger specifications from JSON schema definitions\n\nset -e\nPROJECT_DIRECTORY=\"$( cd \"$( dirname"
  },
  {
    "path": "devtools/api-mock/collection-middleware/index.js",
    "chars": 205,
    "preview": "const createCollectionMiddleware = entityName => data => (req, res, next) => {\n  res.data = {\n    total: data.length,\n  "
  },
  {
    "path": "devtools/api-mock/contacts/data.json",
    "chars": 18260,
    "preview": "[{\n  \"addresses\": [],\n  \"privacy_features\": {},\n  \"phones\": [],\n  \"contact_id\": \"c-john-01\",\n  \"date_insert\": \"2016-05-0"
  },
  {
    "path": "devtools/api-mock/contacts/index.js",
    "chars": 2602,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/devices/data.json",
    "chars": 354,
    "preview": "[\n  {\n    \"device_id\": \"00001\",\n    \"ecdsa_key\": {\n      \"curve\": \"P-256\",\n      \"hash\": \"SHA256\",\n      \"x\": \"fd73920f7"
  },
  {
    "path": "devtools/api-mock/devices/index.js",
    "chars": 3513,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/discussions/data.json",
    "chars": 7251,
    "preview": "[\n  {\n    \"tags\": [\n      {\n        \"tag_id\": \"foo-bar-1\",\n        \"name\": \"robot\",\n        \"type\": \"user\"\n      },\n    "
  },
  {
    "path": "devtools/api-mock/discussions/index.js",
    "chars": 1845,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/local_identities/data.json",
    "chars": 324,
    "preview": "[\n  {\n    \"credentials\": {},\n    \"display_name\": \"Jown d'eau\",\n    \"identity_id\": \"b7a715aa-8fff-4083-9dab-0c85b2634c0b\""
  },
  {
    "path": "devtools/api-mock/local_identities/index.js",
    "chars": 689,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/me/data.json",
    "chars": 1016,
    "preview": "{\n\t\"user_id\": \"u-john-01\",\n\t\"name\": \"Jaune\",\n\t\"given_name\": \"John Dœuf\",\n\t\"contact_id\": \"foobar112\",\n\t\"contact\": {\n\t  \"a"
  },
  {
    "path": "devtools/api-mock/me/index.js",
    "chars": 939,
    "preview": "import { createAction, createSelector } from 'bouchon';\n\nconst actions = {\n  get: createAction('me'),\n  patch: createAct"
  },
  {
    "path": "devtools/api-mock/messages/data.json",
    "chars": 36273,
    "preview": "[{\n  \"attachments\": [],\n  \"body\": \"Fry! Stay back! He's too powerful! Can I use the gun? I barely knew Philip, but as a "
  },
  {
    "path": "devtools/api-mock/messages/index.js",
    "chars": 7185,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v4 as uuidv4 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/notifications/data.json",
    "chars": 1035,
    "preview": "{\n  \"total\": 4,\n  \"notifications\": [\n    {\n      \"emitter\": \"imap_worker\",\n      \"notif_id\": \"aaaa-bbbb-0001\",\n      \"ty"
  },
  {
    "path": "devtools/api-mock/notifications/index.js",
    "chars": 1065,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/oauth-mock/data.json",
    "chars": 3,
    "preview": "[]\n"
  },
  {
    "path": "devtools/api-mock/oauth-mock/index.js",
    "chars": 807,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { actions as remoteIdentActions } from '../remote_identit"
  },
  {
    "path": "devtools/api-mock/package.json",
    "chars": 429,
    "preview": "{\n  \"name\": \"api-mock\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"babel-c"
  },
  {
    "path": "devtools/api-mock/participants/data.json",
    "chars": 3234,
    "preview": "[{\n  \"address\": \"bender@caliopen.local\",\n  \"contact_id\": \"92d3727a-eefc-4537-b879-85f1c9d197bb\",\n  \"label\": \"Bender\",\n  "
  },
  {
    "path": "devtools/api-mock/participants/index.js",
    "chars": 899,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/providers/data.json",
    "chars": 632,
    "preview": "[\n  {\n    \"infos\": {\n      \"client_id\": \"\",\n      \"client_secret\": \"\",\n      \"imapserver\": \"imap.gmail.com:993\",\n      \""
  },
  {
    "path": "devtools/api-mock/providers/index.js",
    "chars": 1573,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/remote_identities/data.json",
    "chars": 3,
    "preview": "[]\n"
  },
  {
    "path": "devtools/api-mock/remote_identities/index.js",
    "chars": 4024,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/search/data.json",
    "chars": 4106,
    "preview": "{\n  \"total\": 2,\n  \"messages_hits\": {\n    \"total\": 2,\n    \"messages\": [\n      {\n        \"highlights\": { \"???\": [\"I like c"
  },
  {
    "path": "devtools/api-mock/search/index.js",
    "chars": 651,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/settings/data.json",
    "chars": 321,
    "preview": "{\n  \"default_locale\": \"en-US\",\n  \"message_display_format\": \"rich_text\",\n  \"contact_display_format\": \"given_name, family_"
  },
  {
    "path": "devtools/api-mock/settings/index.js",
    "chars": 812,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/api-mock/tags/data.json",
    "chars": 619,
    "preview": "[\n  {\n    \"name\": \"INBOX\",\n    \"type\": \"system\"\n  },\n  {\n    \"name\": \"IMPORTANT\",\n    \"type\": \"system\"\n  },\n  {\n    \"nam"
  },
  {
    "path": "devtools/api-mock/tags/index.js",
    "chars": 2364,
    "preview": "import { createAction, createSelector } from 'bouchon';\nimport { v1 as uuidv1 } from 'uuid';\nimport createCollectionMidd"
  },
  {
    "path": "devtools/clean-dev-storage.sh",
    "chars": 276,
    "preview": "#!/bin/bash\n#\n# DEVELOPMENT ONLY SCRIPT\n#\n# Clean docker containers and volumes where data are stored\n\ndocker-compose ki"
  },
  {
    "path": "devtools/conf/proxy-api.conf",
    "chars": 1086,
    "preview": "\nuser  nginx;\nworker_processes  1;\n\nerror_log  /var/log/nginx/error.log warn;\npid        /var/run/nginx.pid;\n\n\nevents {\n"
  },
  {
    "path": "devtools/docker-compose.staging.yml",
    "chars": 4521,
    "preview": "version: '2.1'\nvolumes:\n  index:\n    driver: local\n  db:\n    driver: local\n  store:\n    driver: local\nservices:\n  # Prox"
  },
  {
    "path": "devtools/docker-compose.yml",
    "chars": 5630,
    "preview": "version: '2.1'\nvolumes:\n  index:\n    driver: local\n  db:\n    driver: local\n  store:\n    driver: local\n\nservices:\n  # Pro"
  },
  {
    "path": "devtools/drone/build_images.sh",
    "chars": 221,
    "preview": "#!/bin/bash\nset -e\n\nif [[ $SRC_CHANGED == \"true\" ]];\nthen\n\techo \"Building changes\"\n\t#/usr/local/bin/dockerd-entrypoint.s"
  },
  {
    "path": "devtools/drone/files_changed.sh",
    "chars": 1165,
    "preview": "#!/bin/bash\nset -e\n\nCURRENT_DIR=$(pwd)\nSRC_CHANGED=\"false\"\nBRANCHES=\"\"\n\n# Images based on alpine do not contain git\nif ["
  },
  {
    "path": "devtools/drone/get_go_dependencies.sh",
    "chars": 884,
    "preview": "#!/bin/bash\nset -e\n\nCURRENT_DIR=$(pwd)\nBASE_PACKAGE=github.com/CaliOpen/Caliopen\nPACKAGE=$BASE_PACKAGE/src/backend/$PROG"
  },
  {
    "path": "devtools/drone/get_py_dependencies.sh",
    "chars": 540,
    "preview": "#!/bin/bash\nset -e\n\nDEPS=\"\"\n# Find python requirement file\nREQ_FILE=$(find $BASE_DIR/$PROG -depth -type f -name requirem"
  },
  {
    "path": "devtools/drone/test_front.sh",
    "chars": 168,
    "preview": "#!/bin/bash\nset -e\n\nif [ \"$SRC_CHANGED\" = \"false\" ];\nthen\n\techo \"No changes to frontend\"\n\treturn\nfi\n\ncd src/frontend/web"
  },
  {
    "path": "devtools/drone/test_go.sh",
    "chars": 406,
    "preview": "#!/bin/bash\nset -e\n\nif [ \"$SRC_CHANGED\" = \"false\" ];\nthen\n\techo \"No changes to backend\"\n\treturn\nfi\n\n# Respect GOPATH con"
  },
  {
    "path": "devtools/drone/test_py.sh",
    "chars": 425,
    "preview": "#!/bin/bash\nset -e\n\nif [ \"$SRC_CHANGED\" = \"false\" ];\nthen\n\techo \"No changes to backend\"\n\treturn\nfi\n\ncd src/backend\npip i"
  },
  {
    "path": "devtools/extract/email_graph.py",
    "chars": 3671,
    "preview": "# -*- coding: utf-8 -*-\nfrom __future__ import absolute_import, print_function, unicode_literals\n\nimport argparse\nimport"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_1.argentina:2,",
    "chars": 32914,
    "preview": "Return-Path: <posts@futurfast.eu>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_11.argentina:2,",
    "chars": 14630,
    "preview": "Return-Path: <paypal@service.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_13.argentina:2,",
    "chars": 24252,
    "preview": "Return-Path: <qfzwjsy_0gz7chidgb.4g@carre-parfait.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_15.argentina:2,",
    "chars": 3618,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apWsZ-00069Y-9w\n\tfor mharc-dev@caliopen.local; Mon, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_17.argentina:2,",
    "chars": 9843,
    "preview": "Return-Path: <freemobile@free-mobile.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brains"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_19.argentina:2,",
    "chars": 24366,
    "preview": "Return-Path: <bounce@client.flash-des-affaires.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@br"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_21.argentina:2,",
    "chars": 13327,
    "preview": "Return-Path: <noreply@takel.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\nR"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_23.argentina:2,",
    "chars": 24569,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aeCCN-0000y7-V5\n\tfor mharc-dev@caliopen.local; Thu, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_25.argentina:2,",
    "chars": 3833,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aeIOq-0004XI-2r\n\tfor mharc-dev@caliopen.local; Fri, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_27.argentina:2,",
    "chars": 5288,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1agpPT-00067Y-Js\n\tfor mharc-dev@caliopen.local; Fri, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_29.argentina:2,",
    "chars": 5697,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apROz-0005tg-71\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_3.argentina:2,",
    "chars": 8517,
    "preview": "Return-Path: <bounce@client.mes-offre.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_31.argentina:2,",
    "chars": 2664,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apRk1-0005zO-Dt\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_33.argentina:2,",
    "chars": 3432,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apPbw-0000SZ-RW\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_35.argentina:2,",
    "chars": 4390,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aNWYx-0007Xj-83\n\tfor mharc-dev@caliopen.local; Sun, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_37.argentina:2,",
    "chars": 3420,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aNjKo-0007v8-FW\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_39.argentina:2,",
    "chars": 5113,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoYS4-0001mN-EQ\n\tfor mharc-dev@caliopen.local; Fri, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_41.argentina:2,",
    "chars": 4606,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aonU9-0005Ps-Dm\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_43.argentina:2,",
    "chars": 7512,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoqzC-0001cq-TZ\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_45.argentina:2,",
    "chars": 4842,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apAkT-0001RS-9C\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_47.argentina:2,",
    "chars": 5525,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apPLe-0005Fr-BS\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_49.argentina:2,",
    "chars": 3355,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aorfA-0002Rz-3Q\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_5.argentina:2,",
    "chars": 4366,
    "preview": "Return-Path: <info@pubblicitaaziendedb.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.bra"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_51.argentina:2,",
    "chars": 5533,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aNb7c-0003dG-UV\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_53.argentina:2,",
    "chars": 8024,
    "preview": "Return-Path: <bounce-248-35000120-248-248@kaixiner2.top>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laure"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_55.argentina:2,",
    "chars": 18061,
    "preview": "Return-Path: <tocservice@acm.org>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_57.argentina:2,",
    "chars": 2757,
    "preview": "Return-Path: <lennaenglishh@soswy.state.wy.us>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil."
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_59.argentina:2,",
    "chars": 19363,
    "preview": "Return-Path: <bounce@client.mes-offre.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_61.argentina:2,",
    "chars": 30337,
    "preview": "Return-Path: <posts@futurfast.eu>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_63.argentina:2,",
    "chars": 2063,
    "preview": "Return-Path: <moon98@wevercomm.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm."
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_7.argentina:2,",
    "chars": 9491,
    "preview": "Return-Path: <prvs=0909110163=info@Honeywell-egypt.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: lauren"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463561.5266_9.argentina:2,",
    "chars": 4558,
    "preview": "Return-Path: <info@pubblicitaaziendedb.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.bra"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_101.argentina:2,",
    "chars": 3844,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anvrT-0007Qu-Bh\n\tfor mharc-dev@caliopen.local; Wed, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_103.argentina:2,",
    "chars": 6677,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ao58W-0007eJ-CN\n\tfor mharc-dev@caliopen.local; Thu, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_105.argentina:2,",
    "chars": 3721,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoHbC-0003Sx-4g\n\tfor mharc-dev@caliopen.local; Thu, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_107.argentina:2,",
    "chars": 6373,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anT3f-0000BS-Tr\n\tfor mharc-dev@caliopen.local; Tue, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_109.argentina:2,",
    "chars": 3959,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajCn1-0005Jw-13\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_111.argentina:2,",
    "chars": 6318,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajCt5-00088R-UH\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_113.argentina:2,",
    "chars": 3917,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajC5V-0003gI-63\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_115.argentina:2,",
    "chars": 2922,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajCAx-0006eq-Sd\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_117.argentina:2,",
    "chars": 5638,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajCOp-0003qM-OW\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_119.argentina:2,",
    "chars": 6325,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajCOg-0003cZ-Gd\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_121.argentina:2,",
    "chars": 6103,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajCDJ-0007Zb-Kt\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_123.argentina:2,",
    "chars": 23937,
    "preview": "Return-Path: <jill@awayswinning.xyz>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_125.argentina:2,",
    "chars": 5234,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXiWg-00079X-TA\n\tfor mharc-dev@caliopen.local; Sun, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_127.argentina:2,",
    "chars": 3270,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYQVP-00034h-OH\n\tfor mharc-dev@caliopen.local; Tue, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_129.argentina:2,",
    "chars": 3175,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYczT-0000JW-Hz\n\tfor mharc-dev@caliopen.local; Wed, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_131.argentina:2,",
    "chars": 3086,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYebF-0000wf-98\n\tfor mharc-dev@caliopen.local; Wed, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_133.argentina:2,",
    "chars": 3455,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYewA-0001rI-WC\n\tfor mharc-dev@caliopen.local; Wed, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_135.argentina:2,",
    "chars": 3402,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYfkc-0008KY-8l\n\tfor mharc-dev@caliopen.local; Wed, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_137.argentina:2,",
    "chars": 5580,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoy6l-0005lS-Gc\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_139.argentina:2,",
    "chars": 3013,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apLh9-000203-24\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_141.argentina:2,",
    "chars": 2802,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoyhh-0001Qh-Mm\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_143.argentina:2,",
    "chars": 6177,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoyxs-0005ew-Dx\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_145.argentina:2,",
    "chars": 3283,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYez8-0003pC-At\n\tfor mharc-dev@caliopen.local; Wed, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_147.argentina:2,",
    "chars": 3236,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXt89-0007bi-JB\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_149.argentina:2,",
    "chars": 5882,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXtMM-0002Qu-KZ\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_151.argentina:2,",
    "chars": 3001,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXtXI-0001wM-Je\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_153.argentina:2,",
    "chars": 6101,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXuHY-0005Mg-0Z\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_65.argentina:2,",
    "chars": 9844,
    "preview": "Return-Path: <freemobile@free-mobile.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brains"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_67.argentina:2,",
    "chars": 8815,
    "preview": "Return-Path: <bounce@boomjets.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_69.argentina:2,",
    "chars": 10124,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aj8yH-0004fq-85\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_71.argentina:2,",
    "chars": 2707,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajEVX-0002Id-PE\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_73.argentina:2,",
    "chars": 4789,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ap7dc-0000I2-8Q\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_75.argentina:2,",
    "chars": 3041,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apKbj-00036O-2p\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_77.argentina:2,",
    "chars": 5968,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apM5u-0008Hs-MF\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_79.argentina:2,",
    "chars": 3153,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajAXy-0006Wm-M1\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_81.argentina:2,",
    "chars": 3799,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajBm0-0003fT-4V\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_83.argentina:2,",
    "chars": 3333,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajBzL-0000KA-M7\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_85.argentina:2,",
    "chars": 4388,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ajCUO-0000OY-4u\n\tfor mharc-dev@caliopen.local; Thu, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_87.argentina:2,",
    "chars": 5014,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1amrT2-0006kT-NT\n\tfor mharc-dev@caliopen.local; Sun, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_89.argentina:2,",
    "chars": 2972,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1an5SW-0000cu-7G\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_91.argentina:2,",
    "chars": 6475,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1an5wf-00031K-RD\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_93.argentina:2,",
    "chars": 3690,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anSMF-0002wr-1c\n\tfor mharc-dev@caliopen.local; Tue, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_95.argentina:2,",
    "chars": 6924,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anSmU-00012C-Ea\n\tfor mharc-dev@caliopen.local; Tue, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_97.argentina:2,",
    "chars": 3276,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anaph-0007FO-ND\n\tfor mharc-dev@caliopen.local; Tue, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463562.5266_99.argentina:2,",
    "chars": 7160,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anh66-0001U7-3o\n\tfor mharc-dev@caliopen.local; Wed, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_155.argentina:2,",
    "chars": 3217,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYGH8-0002XB-He\n\tfor mharc-dev@caliopen.local; Tue, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_157.argentina:2,",
    "chars": 5759,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aYHOJ-0004Fr-VN\n\tfor mharc-dev@caliopen.local; Tue, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_159.argentina:2,",
    "chars": 7231,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXtTa-0003ag-6N\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_161.argentina:2,",
    "chars": 5029,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXmIf-0005jB-IQ\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_163.argentina:2,",
    "chars": 5386,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXqsE-0002pJ-H9\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_165.argentina:2,",
    "chars": 5413,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aXsnI-00063L-5z\n\tfor mharc-dev@caliopen.local; Mon, 2"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_167.argentina:2,",
    "chars": 9845,
    "preview": "Return-Path: <freemobile@free-mobile.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brains"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_169.argentina:2,",
    "chars": 7979,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoyLS-0008PG-Fw\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_171.argentina:2,",
    "chars": 3413,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoyqV-0004rJ-4B\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_173.argentina:2,",
    "chars": 6891,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1aoz4a-0005ic-Kr\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_175.argentina:2,",
    "chars": 4060,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1ap5Nd-0000qn-DU\n\tfor mharc-dev@caliopen.local; Sat, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_177.argentina:2,",
    "chars": 8256,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apFvg-00049M-Ob\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_179.argentina:2,",
    "chars": 5790,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apIOa-0003nY-RC\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_181.argentina:2,",
    "chars": 5567,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apByT-0003XK-Mp\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_183.argentina:2,",
    "chars": 3489,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apGnq-0002EM-88\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_185.argentina:2,",
    "chars": 19430,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1apG16-0002M3-AQ\n\tfor mharc-dev@caliopen.local; Sun, 1"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_187.argentina:2,",
    "chars": 20693,
    "preview": "Return-Path: <contact@globalpromo.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstor"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_189.argentina:2,",
    "chars": 7587,
    "preview": "Return-Path: <bounce@client.mes-offre.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_193.argentina:2,",
    "chars": 16076,
    "preview": "Return-Path: <bounce@client.bonnesaffairesdujour.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_195.argentina:2,",
    "chars": 18843,
    "preview": "Return-Path: <bounce@client.mes-offre.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_197.argentina:2,",
    "chars": 35251,
    "preview": "Return-Path: <news@e.fipe457.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\n"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_199.argentina:2,",
    "chars": 2173,
    "preview": "Return-Path: <calderon71@ljrtrust.org>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainsto"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_201.argentina:2,",
    "chars": 2667,
    "preview": "Return-Path: <changl@dunhamwilcox.net>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainsto"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_205.argentina:2,",
    "chars": 3056,
    "preview": "Return-Path: <alvertaparkso@yori-fluteworld.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasi"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_207.argentina:2,",
    "chars": 12718,
    "preview": "Return-Path: <bounce@client.mes-offre.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_209.argentina:2,",
    "chars": 12964,
    "preview": "Return-Path: <EasyShedPlans@quafter.top>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brains"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_211.argentina:2,",
    "chars": 24028,
    "preview": "Return-Path: <info@my.newspartner3.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainsto"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_213.argentina:2,",
    "chars": 18888,
    "preview": "Return-Path: <JessePrince@janight.top>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainsto"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_215.argentina:2,",
    "chars": 10058,
    "preview": "Return-Path: <DefeatingDiabetes@beyear.top>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.bra"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_217.argentina:2,",
    "chars": 2267,
    "preview": "Return-Path: <case384@zttim.ru>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\nR"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_219.argentina:2,",
    "chars": 2123,
    "preview": "Return-Path: <benson11@evault.com.my>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstor"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_221.argentina:2,",
    "chars": 3551,
    "preview": "Return-Path: <>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\nReceived: from me"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_223.argentina:2,",
    "chars": 14236,
    "preview": "Return-Path: <posts@futurfast.eu>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_225.argentina:2,",
    "chars": 4497,
    "preview": "Return-Path: <info@db-gc.net>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\nRec"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_227.argentina:2,",
    "chars": 2245,
    "preview": "Return-Path: <stein359@camarazaragoza.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_229.argentina:2,",
    "chars": 12094,
    "preview": "Return-Path: <bounce@client.mes-offre.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_231.argentina:2,",
    "chars": 2110,
    "preview": "Return-Path: <mcclure218@namimanitoba.org>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_233.argentina:2,",
    "chars": 2165,
    "preview": "Return-Path: <nichols347@new-mebel72.ru>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brains"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_235.argentina:2,",
    "chars": 16516,
    "preview": "Return-Path: <mail@info.astucemail.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainst"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_237.argentina:2,",
    "chars": 9999,
    "preview": "Return-Path: <qfzwjsy_0gz7chidgb.4g@eml-media.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@bras"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_239.argentina:2,",
    "chars": 2275,
    "preview": "Return-Path: <quinn107@desenvolvimento.argo.com.br>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@br"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_241.argentina:2,",
    "chars": 3466,
    "preview": "Return-Path: <>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\nReceived: from me"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463563.5266_243.argentina:2,",
    "chars": 4957,
    "preview": "Return-Path: <derrick@awayswinning.xyz>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainst"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_245.argentina:2,",
    "chars": 4440,
    "preview": "Return-Path: <billing@awayswinning.xyz>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainst"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_247.argentina:2,",
    "chars": 2392,
    "preview": "Return-Path: <>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\nReceived: from me"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_249.argentina:2,",
    "chars": 2570,
    "preview": "Return-Path: <duh@1337.no>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.fr\nReceiv"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_253.argentina:2,",
    "chars": 3733,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1an5nl-0004gy-6m\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_255.argentina:2,",
    "chars": 3885,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1an9ec-0006yZ-Au\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_257.argentina:2,",
    "chars": 3132,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anWzQ-0007Un-Sg\n\tfor mharc-dev@caliopen.local; Tue, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_259.argentina:2,",
    "chars": 4652,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anQlY-0003tb-R3\n\tfor mharc-dev@caliopen.local; Tue, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_261.argentina:2,",
    "chars": 4427,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1an9Tl-0002bZ-T0\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_263.argentina:2,",
    "chars": 2879,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anB4i-00042m-SJ\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_265.argentina:2,",
    "chars": 2132,
    "preview": "Return-Path: <avery715@zspswidwin.pl>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstor"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_267.argentina:2,",
    "chars": 11818,
    "preview": "Return-Path: <bounce@client.mes-offre.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brai"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_269.argentina:2,",
    "chars": 2280,
    "preview": "Return-Path: <white120@gadget.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm.f"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_271.argentina:2,",
    "chars": 3925,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1amuQD-00073j-1v\n\tfor mharc-dev@caliopen.local; Sun, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_273.argentina:2,",
    "chars": 4705,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1amwsR-0006QQ-5S\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_275.argentina:2,",
    "chars": 3306,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1an3nl-0004iZ-Fk\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_277.argentina:2,",
    "chars": 4083,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1anSvh-0002fX-Q2\n\tfor mharc-dev@caliopen.local; Tue, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_279.argentina:2,",
    "chars": 4754,
    "preview": "Received: from list by lists.gnu.org with archive (Exim 4.71)\n\tid 1an6Os-00024Y-3Z\n\tfor mharc-dev@caliopen.local; Mon, 0"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_281.argentina:2,",
    "chars": 2442,
    "preview": "Return-Path: <info@baldwin-park.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_283.argentina:2,",
    "chars": 33383,
    "preview": "Return-Path: <apuestas.es@gmail.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brainstorm"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_285.argentina:2,",
    "chars": 2215,
    "preview": "Return-Path: <ilene_gaines@milicavezmar.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.br"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_287.argentina:2,",
    "chars": 21147,
    "preview": "Return-Path: <CEO@ChinaBestSupplier.com>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent@brasil.brains"
  },
  {
    "path": "devtools/fixtures/mbox/dev@caliopen.local/1460463564.5266_289.argentina:2,",
    "chars": 18067,
    "preview": "Return-Path: <qfzwjsy_0gz7chidgb.4g@trouver-presta.fr>\nX-Original-To: laurent@brasil.brainstorm.fr\nDelivered-To: laurent"
  }
]

// ... and 2225 more files (download for full content)

About this extraction

This page contains the full source code of the CaliOpen/Caliopen GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2425 files (10.9 MB), approximately 3.0M tokens, and a symbol index with 4599 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!