15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/download/download_net_log_parameters.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_interrupt_reasons.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* download_type_names[] = { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NEW_DOWNLOAD", 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "HISTORY_IMPORT", 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SAVE_PAGE_AS" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* download_danger_names[] = { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NOT_DANGEROUS", 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DANGEROUS_FILE", 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DANGEROUS_URL", 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DANGEROUS_CONTENT", 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MAYBE_DANGEROUS_CONTENT", 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "UNCOMMON_CONTENT", 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "USER_VALIDATED", 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DANGEROUS_HOST", 34a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "POTENTIALLY_UNWANTED" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(ARRAYSIZE_UNSAFE(download_type_names) == SRC_SAVE_PAGE_AS + 1, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_type_enum_has_changed); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(ARRAYSIZE_UNSAFE(download_danger_names) == 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DOWNLOAD_DANGER_TYPE_MAX, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_danger_enum_has_changed); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ItemActivatedNetLogCallback( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadItem* download_item, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadType download_type, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string* file_name, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("type", download_type_names[download_type]); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("id", base::Int64ToString(download_item->GetId())); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("original_url", download_item->GetOriginalUrl().spec()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("final_url", download_item->GetURL().spec()); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("file_name", *file_name); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("danger_type", 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_danger_names[download_item->GetDangerType()]); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("start_offset", 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Int64ToString(download_item->GetReceivedBytes())); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetBoolean("has_user_gesture", download_item->HasUserGesture()); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ItemCheckedNetLogCallback( 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadDangerType danger_type, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("danger_type", download_danger_names[danger_type]); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* ItemRenamedNetLogCallback(const base::FilePath* old_filename, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath* new_filename, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("old_filename", old_filename->AsUTF8Unsafe()); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("new_filename", new_filename->AsUTF8Unsafe()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ItemInterruptedNetLogCallback(DownloadInterruptReason reason, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 bytes_so_far, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string* hash_state, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason)); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("hash_state", 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::HexEncode(hash_state->data(), hash_state->size())); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* ItemResumingNetLogCallback(bool user_initiated, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadInterruptReason reason, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 bytes_so_far, 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string* hash_state, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog::LogLevel log_level) { 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("user_initiated", user_initiated ? "true" : "false"); 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason)); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("hash_state", 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HexEncode(hash_state->data(), hash_state->size())); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dict; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ItemCompletingNetLogCallback(int64 bytes_so_far, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string* final_hash, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("final_hash", 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::HexEncode(final_hash->data(), final_hash->size())); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ItemFinishedNetLogCallback(bool auto_opened, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("auto_opened", auto_opened ? "yes" : "no"); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ItemCanceledNetLogCallback(int64 bytes_so_far, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string* hash_state, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("hash_state", 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::HexEncode(hash_state->data(), hash_state->size())); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* FileOpenedNetLogCallback(const base::FilePath* file_name, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 start_offset, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("file_name", file_name->AsUTF8Unsafe()); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("start_offset", base::Int64ToString(start_offset)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* FileStreamDrainedNetLogCallback(size_t stream_size, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_buffers, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger("stream_size", static_cast<int>(stream_size)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger("num_buffers", static_cast<int>(num_buffers)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* FileRenamedNetLogCallback(const base::FilePath* old_filename, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath* new_filename, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("old_filename", old_filename->AsUTF8Unsafe()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("new_filename", new_filename->AsUTF8Unsafe()); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* FileErrorNetLogCallback(const char* operation, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::Error net_error, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("operation", operation); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger("net_error", net_error); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* FileInterruptedNetLogCallback(const char* operation, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int os_error, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadInterruptReason reason, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::LogLevel log_level) { 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("operation", operation); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (os_error != 0) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger("os_error", os_error); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 209