sicos1977 / msgkit Goto Github PK
View Code? Open in Web Editor NEWA .NET library to make MSG files without the need for Outlook
A .NET library to make MSG files without the need for Outlook
Hi,
I have other attributes(PidTag****) which I want to add to the mail item. Is it possible to add these custom attributes ?
--Srinu
Please write and implement method for msg to eml
I'm looking to save the msg as a draft. Is there a current property i'm missing that can be set or one that could be added?
Thanks!
Create a msg file with attachments, save the file and try to recreate the file again. I keep on receiving the file is being used by another process error.
Your last change to fix appointments worked perfectly so thank you for the quick turnaround. Unfortunately, setting the body text in an email to HTML is now broken and always goes back to setting body text as text.
I get NullRef exception when trying to use AddLink()
function on the Attachments
, and then try to save the e-mail.
It's like the wrong Attachment ctor
get's called.
Also it would be really handy to have access to the Attachment
ctor.
using (var email = new Email(
new Sender("[email protected]", "Peter Pan"),
new Representing("[email protected]", "Tinkerbell"),
"Hello Neverland subject"))
{
email.Recipients.AddTo("[email protected]", "Captain Hook");
email.Recipients.AddCc("[email protected]", "The evil ticking crocodile");
email.Subject = "This is the subject";
email.BodyText = "Hello Neverland text";
email.BodyHtml = "<html><head></head><body><b>Hello Neverland html</b></body></html>";
email.Importance = MessageImportance.IMPORTANCE_HIGH;
email.IconIndex = MessageIconIndex.ReadMail;
email.Attachments.AddLink(new FileInfo(@"d:\crocodile.jpg"));
email.Save(@"c:\email.msg");
// Show the E-mail
System.Diagnostics.Process.Start(@"c:\email.msg");
}
It throws NRE.
{"Object reference not set to an instance of an object."}
at MsgKit.Attachment.WriteProperties(CFStorage storage, Int32 index)
at MsgKit.Attachments.WriteToStorage(CFStorage rootStorage)
at MsgKit.Email.WriteToStorage()
at MsgKit.Email.Save(String fileName)
Hi,
could you please add a feature to add a KeyValuePairs to MSG headers as one is able to do so with System.Net.Mail.MailMessage?
Currently I'm trying to add X-Unsent=1 header - with no success.
Thanks and cheers,
David
GetShortFileName Method in this file doesn't checks string length:
name = name.Substring(0, 6).ToUpperInvariant() + "~1";
and
name += "." + extension.Substring(1, 3).ToUpperInvariant();
and throws Index and length must refer to a location within the string for filenames like that "te.st"
I think it should be like that:
name = (name.Length > 8 ? name.Substring(0, 6) + "~1" : name).ToUpperInvariant();
and
name += "." + (extension.Length > 3 ? extension.Substring(1, 3) : extension.TrimStart('.')).ToUpperInvariant()
Hello,
If I add Attachements with the following code and the name of the Attachement already exists I get an error:
MsgKit.Exceptions.MKAttachmentExists: "The attachment with the name 'Karpathos.msg' already exists"
here my code:
email.Attachments.Add(dokument.Dokumentinhalt.ToMemoryStream(), fileName);
what's the best way to avoid this error?
robert
Below code works in version 1.2.4 but NOT in 2.1.0. Any idea why?
email.Attachments.Add(fileStream, ReplaceInvalidCharachtersInString(name), -1, true,
attachment.GetAttributeValue(AttachmentStatics.FileName));
Hi, thanks again for the great tool. While compiling I noticed an error because the NamedProperties class could not be found. I changed the PropertyNames class to NamedProperties (it was indicated the original filename was NamedProperties.cs at the top of the PropertyNames.cs file). Ran into another little issue with the inaccessible protection level (internal). Changed to public and it compiled, but I suspect this may be a bit heavy-handed.
When creating a email in outlook with embedded images, the images never show as attachments to the email, to the recipient or in my sent folder.
When I create a draft email with MsgKit and save it, then open with outlook; the embedded images don't show as attachments. But, when I send the email, the images show up as attached files to the recipient and also the same in my sent folder.
how to download the file in extension dll?
Hi, thanks for the great tool. I'm playing around with it and I noticed a couple of issues. I'll file them as separate bugs for you. The first issue is that when I create an MSG file using the sample testing tool you provided, it seems to subtract 4 hours from the current time. As an example, I chose March 1, 2017 with the datepicker control, and saved at 12:06:39 PM. When I opened the file it indicated the creation date of March 1, 2017 at 8:06:39 AM. Not sure if the issue is with the datepicker control or elsewhere.
Hello,
very useful library. However, I am having a problem. If I try to save an email that has an .msg file as attachment, the attachment doesn't open. It says "resource is busy or you lack sufficient access rights or permissions". Do you know how to fix this?
Thanks
This is not really a bug. However, I cannot figure out how to set a request for read receipt or delivery receipt when creating a draft. I was hoping it would be as simple as changing the priority of the message but I could not find any properties like that.
If there is a way of requesting a read receipt or delivery receipt when creating a draft, please let me know what it is. Otherwise, this is a feature request.
I am using C# to generate a .MSG draft file so we can open it in Outlook, review the message and attachments, and send it using Outlook.
Desktop (please complete the following information):
Windows 7 32-bit
James Roes
I can't create working msg-files with BodyHtml and mail in draft mode.
The result in Outlook is an mail, where not html is available.
Is draft = false, all is ok ...
When you set the subject to string.Empty, and exception is thrown in Email.cs line 252, this is because you are trying to substring a empty string.
Hi - I am trying to add a custom property to an email. the property value is a string and holds information. I need to use the info in an outlook add-ons after sending the email to store it in a database . I went through all propertytags to see which one I can use. but I couldn't find any that is specific to custom property (user define field). I want to create a new propertytag but then I can not set name and value. I used the code below, but I could n't open the mail after adding them.
// Add a custom property
email.AddProperty(PropertyTags.PR_AUTO_FORWARDED, true);
email.AddProperty(PropertyTags.PR_AUTO_FORWARD_COMMENT_W, "entrytype,entryID,xxx");
I appreciate if you get back to me.
Thanks,
Sanaz
When loading NuGet package 1.1.1, the following problem occured when running the sample code from the Read.me file.
FileLoadException: Could not load file or assembly 'OpenMcdf, Version=2.1.0.33051, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044).
Any idea on how to deal with this.
public static void SaveEmailWithAttachments(string subject, string body,string emailFileName, string filesLocation, string sharedPath,List selectedFileList)
{
/*
MailMessage mail = new MailMessage();
mail.Body = body;
mail.To.Add(new MailAddress(""));
mail.From = new MailAddress("");
mail.Subject = subject;
string[] fileEntries = Directory.GetFiles(filesLocation);
foreach (string fileName in fileEntries)
{
if (File.Exists(fileName))
{
//if (selectedFileList.Any(a => a == fileName))
//{
Attachment attachment = new Attachment(fileName, MediaTypeNames.Application.Octet);
ContentDisposition disposition = attachment.ContentDisposition;
disposition.CreationDate = File.GetCreationTime(fileName);
disposition.DispositionType = DispositionTypeNames.Attachment;
mail.Attachments.Add(attachment);
//}
}
}
try
{
string emailFile = Path.Combine(filesLocation, emailFileName);
string emailFileWithEML = Path.ChangeExtension(emailFile, ".EML");
mail.Save(emailFileWithEML);
Independentsoft.Email.Mime.Message mimeMessage = new Independentsoft.Email.Mime.Message(emailFileWithEML);
Independentsoft.Msg.Message msgMessage = new Independentsoft.Msg.Message(mimeMessage);
msgMessage.Save(sharedPath);
if (File.Exists(emailFileWithEML))
{
File.Delete(emailFileWithEML);
}
}
catch (Exception)
{
}
*/
try
{
using (var email = new Email(
new Sender("", ""), subject,true))
{
//email.Recipients.AddTo("", "");
//email.Recipients.AddCc(" ", "");
email.Subject = subject;
// email.BodyText = "Hello Neverland text";
email.BodyHtml = body;
//email.Importance = MessageImportance.IMPORTANCE_HIGH;
email.IconIndex = MessageIconIndex.UnsentMail;
string[] fileEntries = Directory.GetFiles(filesLocation);
foreach (string fileName in fileEntries)
{
if (File.Exists(fileName))
{
email.Attachments.Add(fileName);
//Stream fs = File.OpenRead(fileName);
// email.Attachments.Add(fs,fileName);
}
}
email.Save(sharedPath);
// Show the E-mail
}
}
catch (Exception e)
{
Log.Error("Error: " + e.Message, e);
}
}
Hello !
Could MsgKit be used to generate .oft files ?
Thanks !
Recently, the MSG file created by msgkit seems to be opened as read-only by Outlook 365. I believe Outlook 365 may have changed their .msg file format.
Hello Kees,
first thanks for the two great MSG libraries that you have here!
The task I would like to accomplish is reading an existent MSG file, adding an attachment and saving the MSG file again.
I see that your library MSGReader supports reading MSG files which works fine in my test, but unfortunately it seems this library does not support adding attachments (only deleting them).
And the library MsgKit here seems to only support creating new MSGs completely from scratch, but not loading existent ones or did I miss something?
Therefore my question:
What's the best way to load an existent MSG file, add an attachment to it and save it again?
Thanks in advance
Andreas
P. S.: Would it maybe not even make sense to combine those two libraries to one?
Hi Sicos,
I've tried to attach files to an email from the file system, I then save the email, that works and can move the email to its final destination, however when I go to delete the files, windows says the files are still in use. The process of attaching the file to the email is holding the file open, you must have a dispose class that hasn't been called? Only after my application is closed, can I delete the files.
I switched to using streams which was probably better for my application but I had issues creating attachments from a stream, the attachments were empty, the fix was to ensure the stream position was set to zero before passing it through to the email object. I would have thought that your code should check the stream is at position zero?
Let me know if you want anymore information.
Many thanks,
Tim
Is it possible to create a item with no sender set? When creating a draft, I'd like to have no sender and let Outlook set this when they actually send the email.
Hi Kees,
Full error: Could not load file or assembly 'OpenMcdf, Version=2.0.5739.40493, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Running VS 2015
<package id="MimeKit" version="1.16.1" targetFramework="net452" />
<package id="MsgKit" version="1.1.2" targetFramework="net452" />
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net452" />
<package id="OpenMcdf" version="2.1.0.33051" targetFramework="net452" />
MsgKit 1.1.2 is looking for 2.0.5739.40493 OpenMcdf, due to dependancies I can't install that version of OpenMcdf... can you compile a new nuget version?
What are the options for sending a msg created with MsgKit? Is there a way to use the SmtpClient without adding the file as an attachment? I'm trying to replicate sending an appointment just like Outlook would without having Outlook installed. The only thing I can think of is to put it into a folder where an SMTP server (IIS) takes the files and sends them automatically, but I'd prefer to use SmtpClient if possible.
Hi, thanks again for the great tool. I ran into one more issue. The text "für" is showing up as "f??r" in the display. Seems to be an encoding issue of some sort. I can provide sample .msg files if required.
Anywhere I can find examples of using inline messages with MsgKit? I am concatenating the signature file of outlook to an existing html and using that as the source for BodyHtml. I think if I knew to use inline files, I could copy or change the image as needed.
When I use to optional draft parameter of the Email Class, the HTML-String assigned to the BodyHtml-Property is not displayed in the saved Msg-File. If I set the draft parameter to false the HTML-Body is displayed, but Msg-File is in Read-Only-Mode.
How I can create a task with this librairy?
Hello, is it possible to add a reply to adress?
robert
Hi,
Just a minor issue:
The above error occurs on a slightly messy solutions/projects. The solution contains a few projects and is basically on ASP Core 2.1 but targeting full .net 472. One of the projects cosumes MsgKit installed through Nuget, it also targets 472.
After updated to MsgKit 1.2.7, the error message saying version conflict has disappeared (thanks!) but now it causes exception saying the subject at runtime. If I go Nuget again and down-grade the OpenMcdf to Version 2.1.6.28924, it works fine, i.e. no exceptions. The solution does not use OpenMcdf directly but only through MsgKit.
Cheers,
Hi,
I am trying to create an e-mail file (.msg) but always gives the same error.
Code:
using (MsgKit.Email email = new MsgKit.Email(new MsgKit.Sender(authUser.Email, authUser.Name), string.Empty))
{
email.BodyHtml = GenerateInlineHTML(key, srcCode, Server);
//email.Save(stream);
//byte[] teste = ObjectToByteArray((object)email);
switch (key)
{
case "SPECIALS":
path = VariablesRep.CODE_SPECIALS_FOLDER_W + @"E-mails\";
break;
}
email.Save(path + emailFileName);
//emailFile.Add("e-mail", JObject.FromObject(new MultipartFile(new MemoryStream(teste), "e-mail", emailFileName)));
}
And, this is the error:
[ArgumentNullException: String reference not set to a string instance.
Parameter name: s]
System.Text.Encoding.GetBytes(String s) +12586649
MsgKit.Helpers.Strings.WriteNullTerminatedUnicodeString(BinaryWriter binaryWriter, String str) in C:\Users\AO303388\source\repos\MsgKit\MsgKit\Helpers\Strings.cs:134
MsgKit.Structures.OneOffEntryId.ToByteArray() in C:\Users\AO303388\source\repos\MsgKit\MsgKit\Structures\OneOffEntryId.cs:172
MsgKit.Sender.WriteProperties(TopLevelProperties propertiesStream) in C:\Users\AO303388\source\repos\MsgKit\MsgKit\Sender.cs:111
MsgKit.Email.WriteToStorage() in C:\Users\AO303388\source\repos\MsgKit\MsgKit\Email.cs:369
MsgKit.Email.Save(String fileName) in C:\Users\AO303388\source\repos\MsgKit\MsgKit\Email.cs:486
FAMO.CODE.Controllers.d__3.MoveNext() in L:\TFS\DOTNET\Development\FAMO.CODE\FAMO.CODE\Controllers\GlobalController.cs:91
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +97
System.Web.Mvc.Async.<>c__DisplayClass8_0.b__1(IAsyncResult asyncResult) +17
System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase
1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.AsyncInvocationWithFilters.b__11_0() +50
System.Web.Mvc.Async.<>c__DisplayClass11_1.b__2() +228
System.Web.Mvc.Async.<>c__DisplayClass7_0.b__1(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase
1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
System.Web.Mvc.Async.<>c__DisplayClass3_6.b__3() +35
System.Web.Mvc.Async.<>c__DisplayClass3_1.b__5(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase
1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.<>c.b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState) +11
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase
1.End() +49
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +45
System.Web.Mvc.<>c.b__151_2(IAsyncResult asyncResult, Controller controller) +13
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase
1.End() +49
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c.b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState) +28
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase
1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +577
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +132
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +163
Currently there is no legal way to set value of Email.ReceivedOn
property as it has private setter. Please make the setter public.
Hi,
I'm trying to add attachments, however, i would like to understand how can I add the embedded attachment using stream object. Please provide or point me any example
Thanks in advance.
--Srinu
Subject of the email is: 7.59
When creating the email object, I'm getting this error:
- $exception {"startIndex cannot be larger than length of string.\r\nParameter name: startIndex"} System.ArgumentOutOfRangeException
this stacktrace:
StackTrace " at System.String.Substring(Int32 startIndex, Int32 length)\r\n at MsgKit.Email.SetSubject() in C:\\Users\\Kees\\Documents\\GitHub\\MsgKit\\MsgKit\\Email.cs:line 236\r\n at MsgKit.Email..ctor(Sender sender, Representing representing, String subject) in C:\\Users\\Kees\\Documents\\GitHub\\MsgKit\\MsgKit\\Email.cs:line 208\r\n at CreateMSG.Program.Main(String[] args) in V:\\Testing\\CSharpCreateMSG\\CreateMSG\\Program.cs:line 25" string
code:
var email = new Email(
new Sender("[email protected]", "Peter Pan"),
new Representing("[email protected]", "Tinkerbell"),
"7.59");
// "Hello Neverland subject");
Hello !
Is it possible to build a message with an Active Directory type address to have the contact calendar during the meeting organization ?
This is the X400 address type but it is not interpreted by Outlook ...
Thank you !
Hi,
I am trying to convert Microsoft.Graph.Message to MsgKit.Email so that i can save the email as .msg file. Images does not appear in my .msg file. Please educate me as what i am missing.
Below is the code snippet.
var email = new Email(new Sender(message.Sender.EmailAddress.Address, message.Sender.EmailAddress.Name), message.Subject);
email.SentOn = DateTimeOffset.Parse(message.SentDateTime.ToString()).DateTime;
email.ReceivedOn = DateTimeOffset.Parse(message.ReceivedDateTime.ToString()).DateTime;
email.InternetMessageId = message.InternetMessageId;
//Importance
switch (message.Importance)
{
case Importance.Low:
email.Importance = MessageImportance.IMPORTANCE_LOW;
break;
case Importance.Normal:
email.Importance = MessageImportance.IMPORTANCE_NORMAL;
break;
case Importance.High:
email.Importance = MessageImportance.IMPORTANCE_HIGH;
break;
}
//To
foreach (var to in message.ToRecipients)
{
email.Recipients.AddTo(to.EmailAddress.Address, to.EmailAddress.Name);
}
//Cc
foreach (var cc in message.CcRecipients)
{
email.Recipients.AddCc(cc.EmailAddress.Address, cc.EmailAddress.Name);
}
//Bcc
foreach (var bcc in message.BccRecipients)
{
email.Recipients.AddBcc(bcc.EmailAddress.Address, bcc.EmailAddress.Name);
}
switch (message.Body.ContentType)
{
case BodyType.Text:
email.BodyText = message.Body.Content;
break;
case BodyType.Html:
email.BodyHtml = message.Body.Content;
break;
default:
email.BodyText = message.Body.Content;
break;
}
if (message.HasAttachments == true)
{
foreach (dynamic attachmentFile in message.Attachments)
{
if (attachmentFile.ODataType.ToLower() == ("#microsoft.graph.fileAttachment").ToLower())
{
var fileStream = new MemoryStream(attachmentFile.ContentBytes);
email.Attachments.Add(fileStream, attachmentFile.Name, -1, attachmentFile.IsInline, attachmentFile.Id);
}
else if (attachmentFile.ODataType.ToLower() == ("#microsoft.graph.itemAttachment").ToLower())
{
email.Attachments.Add(attachmentFile.Name, -1, attachmentFile.IsInline, attachmentFile.Id);
}
}
}
@Sicos1977 Is it possible to parse a stream back to its initial properties?
i have my contents of a Msg File as byte array . Could you share a sample piece of code on how to achieve it?
Thanks
Can you provide some example to save as file stream insted of saving in the target location.
When using the sample code to create an appointment, the resultant .msg file opens as an email rather than an appointment when using outlook 2013. We've tried this on a few different machines.
The email sample works with no problems. Any ideas?
No way to create appointments, I can see how to create an email. But I don't think appointments is implemented yet.
my email message body has the picture in it,when save iand open the *.msg file ,the inserted picture is not getting displayed.
Overview
I am trying to add sender/recipient information as "EX" addresses, but when I verify in Outlook, the created MSG files are unable to resolve to the address in AD, and I know 100% that the EX addresses are valid, and they resolve when using MSGs created from the Outlook Interop library.
Code
const string address = "/o=Company/ou=Exchange Group (XYBZHF23456LT)/cn=Recipients/cn=User Name";
var sender = new Sender(address, "Display, Name", MsgKit.Enums.AddressType.Ex, canLookupEmailAddress: true);
var subject = "Hello Neverland subject";
using (var email = new Email(sender, subject))
{
email.Recipients.AddTo("/o=Company/ou=Exchange Group (XYBZHF23456LT)/cn=Recipients/cn=User Name", "Display, Name", MsgKit.Enums.AddressType.Ex);
email.Save(@"C:\temp\email.msg");
}
// using MSGReader
using (var msg = new Storage.Message(@"C:\temp\email.msg"))
{
var email = msg.Sender.Email; //this is an empty string
var recipient = msg.Recipients.Single(); // this data appears* to be valid
}
Explanation
It seems to me that the MsgKit library is incorrectly writing sender and recipient data when it is in an "EX" format, causing it to be unable to be resolved when opened in Outlook. When analyzing the data with your MSGReader library, when in "EX" format, the email address always shows as an empty string, which may be an issue w/ MSGReader library, b/c in Outlook the "EX" address does show, but just doesn't resolve to the given user, and simply displays in the following format in the sender area of Outlook:
Display, Name </o=Company/ou=Exchange Group (XYBZHF23456LT)/cn=Recipients/cn=User Name>
The recipient information appears to be valid from the MSGReader library, but the "EX" addresses still fail to do a lookup when opened in Outlook.
Notes
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.